#1 6. Juli 2007 So, mein Problem ist wenn ich einen String mit Winsock versende/empfange dann teilt er jedes Wort in einem Satz sodas jedes Wort in einer eigenen Zeile steht. Was kann ich dagegen machen? {bild-down: http://toschk.pytalhost.com/RR/konsole.gif} server.cpp: Code: #include <windows.h> #include <winsock2.h> #include <iostream> int startWinsock() { WSADATA wsa; return WSAStartup(MAKEWORD(2,0),&wsa); } void startSockTest(long rc) { if(rc!=0){printf("Fehler: Winsock konnte nicht gestartet werden\n");}else{printf("Winsock gestartet...\n");} } void SockTest(SOCKET s) { if(s==INVALID_SOCKET){printf("Fehler: Socket konnte nicht geöffnet werden\n");}else{printf("Socket geoeffnet...\n");} } void bindTest(long rc) { if(rc==SOCKET_ERROR){printf("Fehler: Bind gescheitert, Fehlercode: %d\n",WSAGetLastError());}else{printf("Socket an Port gebunden...\n");} } void listenTest(long rc) { if(rc==SOCKET_ERROR){printf("Fehler: Listen konnte nicht ausgeführt werden, Fehlercode: %d\n", WSAGetLastError());}else{printf("Socket ist im Listen-Modus...\n");} } void connTest(SOCKET a) { if(a == INVALID_SOCKET){printf("Fehler: Verbindung kann nicht aufgebaut werden, Fehlercode: %d\n", WSAGetLastError());}else{printf("Verbindung wurde akzeptiert...\n");} } ///////////////////////////////////////// int main() { long rc = startWinsock(); SOCKET acceptSocket = socket(AF_INET, SOCK_STREAM, 0); SOCKET connectedSocket; SOCKADDR_IN addr; memset(&addr,0, sizeof(SOCKADDR_IN)); addr.sin_family = AF_INET; addr.sin_port = htons(5456); addr.sin_addr.s_addr = ADDR_ANY; rc = bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR)); rc = listen(acceptSocket, 10); connectedSocket = accept(acceptSocket, NULL, NULL); startSockTest(rc); SockTest(acceptSocket); bindTest(rc); listenTest(rc); connTest(connectedSocket); char text[100]; char text2[100]; while(rc!=SOCKET_ERROR) { rc = recv(connectedSocket,text, sizeof(text), 0); text[rc] = '\0'; strcpy(text2, text); printf("%s\n", text2); } closesocket(acceptSocket); closesocket(connectedSocket); WSACleanup(); system("PAUSE"); return 0; } ///////////////////////////////////////// client.cpp Code: #include <windows.h> #include <winsock2.h> #include <iostream> using namespace std; int startWinsock() { WSADATA wsa; return WSAStartup(MAKEWORD(2,0),&wsa); } void startSockTest(long rc) { if(rc!=0){printf("Fehler: Winsock konnte nicht gestartet werden\n");}else{printf("Winsock gestartet...\n");} } void SockTest(SOCKET s) { if(s==INVALID_SOCKET){printf("Fehler: Socket konnte nicht geöffnet werden\n");}else{printf("Socket geoeffnet...\n");} } void connTest(long rc) { if(rc==SOCKET_ERROR){printf("Fehler: Connect gescheitert, Fehlercode: %d\n",WSAGetLastError());}else{printf("Verbindung aufgebaut...\n");} } ///////////////////////////////////////// int main() { long rc = startWinsock(); SOCKET s = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addr; memset(&addr,0,sizeof(SOCKADDR_IN)); addr.sin_family = AF_INET; addr.sin_port = htons(5456); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); rc = connect(s, (SOCKADDR*)&addr, sizeof(SOCKADDR)); startSockTest(rc); SockTest(s); connTest(rc); char text2[100]; char text[100]; while(true){ cin >> text2; strcpy(text, text2); send(s, text, sizeof(text), 0); } closesocket(s); WSACleanup(); system("PAUSE"); return 0; } ///////////////////////////////////////// + Multi-Zitat Zitieren
#2 6. Juli 2007 AW: C Winsock und Strings Hi ! Code: [...] printf("%s\n", text2); [...] Versuch mal: Code: printf ("\'%s\'\n", text2); Dann sieht man genauer, was du empfaengst. Code: cin >> text2; strcpy(text, text2); send(s, text, sizeof(text), 0); Fehleranfaellig: 1. strcpy -> strncpy 2. sizeof (text) -> Wenn es ein Pointer ist, ist er nur 4 bzw. 8 bytes gross, dann sendet er nur 4 bzw. 8. Deshalb durch '100' ersetzen. Du solltest aber keine 'Magic Numbers' benutzen. Also am besten #define MAX_BUF 100, und dann immer 'MAX_BUF' benutzen ( bzw. MAX_BUF - 1 ). --- Es gibt 2 Moeglichkeiten, warum es nicht funktioniert. 1. 'cin' liest jeweils nur 1 'Wort' ein, und dann geht die Funktion weiter 2. TCP-Protokoll. Sendet die Daten zwar als Stream, und sie kommen in der richtigen Reihenfolge an, aber nicht wie sie als Pakete verschickt wurden: Beispiel: Client sendet ( in 1 Befehl, in 1 CharArray ): Server bekommt aber 3 Pakete: Das ist eine Eigenheit des TCP-Protokolls und kann mithilfe von Delimitern kontrolliert werden. Mfg, Kolazomai + Multi-Zitat Zitieren
#3 10. Juli 2007 AW: C Winsock und Strings das problem ist damit leider nicht behoben. Hab nen bisschen nach Delimitern gegoogelt aber leider brauchbares nix gefunden. + Multi-Zitat Zitieren
#4 10. Juli 2007 AW: C Winsock und Strings Mit Delimitern ist gemeint, dass du solange von der Tastatur einliest, bist das Zeichen \r oder \n ist. Die stehen ja für einen Zeilenumbruch, also Enter-Taste-gedrückt. Dann kannst du einfach alles schicken, was bis zum \r oder \n eingegeben wurde. + Multi-Zitat Zitieren
#5 10. Juli 2007 AW: C Winsock und Strings ja dachte ich mir schon. das problem ist das winsock die daten zerstückelt. ich übergib ja der send fuktionen nen vollständiges Array (String). nur kommt es nicht auf einmal an. + Multi-Zitat Zitieren
#6 10. Juli 2007 AW: C Winsock und Strings Hi! Deshalb brauchst ja auch einen Delimiter. Du empfaengst dann mitm Server so lange, bis der Delimiter kommt, und dann weisst du, was die ganze Message war. Das verhindert dann beides, sowohl, dass zu wenig, als auch, dass zu viel kommt. Beispiel: Der Delimiter ist '\n' ( Das ist haeufig der Fall, da man '\n' schwer schreiben kann ). Client sendet: Code: BEFEHL EINS\n Code: BEFEHL ZWEI\n Server empfaengt: Code: BEFEHL EINS\nBEFEHL ZWEI\n Jetzt einfach bei '\n' splitten, und schon hast du die Befehle, so wie sie gesendet wurden Du musst halt schaun, dass da auch ein '\n' ist, weil er sonst ja nicht splitten kann. Wenn es kein '\n' gibt, weisst du, dass der Befehl noch nicht vollstaendig empfangen wurde. Mfg, Kolazomai + Multi-Zitat Zitieren
#7 10. Juli 2007 AW: C Winsock und Strings gut klingt einleuchtend. mit welchen funktionen in verbindung mit winsock also send() und recv() stell ich das an. bei tastatureingaben benutzt man ja getline(). + Multi-Zitat Zitieren
#8 10. Juli 2007 AW: C Winsock und Strings Hi ! C Funktionen: strncat () -> An den Buffer, mit dem du was empfaengst, anfuegen strcspn () -> Schaun, ob Delimiter im Buffer strtok () -> Splitten In C++ geht das mit dem 'string' type bestimmt schoener. Mfg, Kolazomai + Multi-Zitat Zitieren