Verbindung durch Client geschlossen



  • Hallo,

    ich habe eine einfache Server<->Client Kommunikation geschrieben. Das Problem ist der Client sendet Daten(ein String) und die recv() funktion des Servers, beendet mit dem Fehlercode 10054.

    Jetz habe ich gedacht das es sein kann, das es am ACK austausch Prozess zwischen Server und Client liegt, da der Paketaustausch auch eine gewisse Zeit erfordert und deshalb der recv() fehlschlägt. Ich habe eine Pause von 3 sekunden dazwischen gebaut. Jetzt beendet recv() mit 0 was soweit ich weiß bedeutet das der Client die Verbindung (gracefull), also höfflich beendet hat. Nun weiß ich überhaupt nicht mehr weiter.

    Hier der Code:

    Server:

    #pragma comment (lib,"ws2_32.lib")
    
    #include <Windows.h>
    #include <iostream>
    #include <stdlib.h>
    
    using namespace std;
    
    int main(){
    	//----------WSA Starten--------------//
    	WSADATA wsadata;
    	int rc = WSAStartup(MAKEWORD(2,0),&wsadata);
    
    	if(rc != 0){
    		cout << "WSA: Fehler " << GetLastError() << endl;
    		getchar();
    		WSACleanup();
    		return 1;
    	}
    	//------------Socket erstellen----------//
    	SOCKET server;
    	server = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    	//----------Addressinfo---------------//
    	SOCKADDR_IN addr;
    	addr.sin_family = AF_INET;
    	addr.sin_addr.s_addr = INADDR_ANY;
    	addr.sin_port = htons(50000);
    	//--------Port binden--------------//
    	rc = bind(server,(SOCKADDR *)&addr,sizeof(addr));
    
    	if(rc == SOCKET_ERROR){
    		cout << "bind(): Fehler " << GetLastError() << endl;
    		getchar();
    		WSACleanup();
    		return 1;
    	}
    	cout << "Port gebunden an " << ntohs(addr.sin_port) << endl;
    	//---------Listen modus------------//
    	rc = listen(server,10);
    
    	if(rc == SOCKET_ERROR){
    		cout << "listen(): Fehler " << GetLastError() << endl;
    		getchar();
    		WSACleanup();
    		return 1;
    	}
    	cout << "Server ist im listen-Modus..." << endl;
    	//--------Verbindung akzeptieren------------//
    	SOCKET acceptSocket; // für accept, vorübergehend
    	SOCKADDR_IN Quelle;
    	int Qlaenge = sizeof(Quelle);
    
    	acceptSocket = accept(server,(SOCKADDR *)&Quelle,&Qlaenge);
    
    	if(acceptSocket == INVALID_SOCKET){
    		cout << "accept(): Fehler " << GetLastError() << endl;
    		getchar();
    		WSACleanup();
    		closesocket(server);
    		return 1;
    	}
    	cout << "Neue Verbindung mit " << inet_ntoa(Quelle.sin_addr) << " : " << ntohs(Quelle.sin_port) << " akzeptiert" << endl;
    	//--------Nachricht erhalten---------//
    	cout << "Warte auf Nachricht " << endl;
    	char buffer[100] = "";
    
    	int brecv = recv(acceptSocket,buffer,strlen(buffer),0);
    	if(brecv > 0){
    		buffer[brecv] = 0;
    		cout << brecv << " bytes an Daten erhalten" << endl;
    		cout << "Nachricht: " << buffer << endl;
    	}
    	else if(brecv == SOCKET_ERROR){
    		cout << "recv()_Error " << GetLastError() << endl;
    		getchar();
    		WSACleanup();
    		closesocket(server);
    		return 1;
    	}
    	//--------------Aufräumen--------------//
    	WSACleanup();
    	closesocket(server);
    	closesocket(acceptSocket);
    	getchar();
    
    	return 0;
    }
    

    Client:

    #pragma comment (lib,"ws2_32.lib")
    
    #include <Windows.h>
    #include <iostream>
    #include <stdlib.h>
    
    using namespace std;
    
    int main(){
    	//----------WSA Starten--------------//
    	WSADATA wsadata;
    	int rc = WSAStartup(MAKEWORD(2,0),&wsadata);
    
    	if(rc != 0){
    		cout << "WSA: Fehler " << GetLastError() << endl;
    		getchar();
    		WSACleanup();
    		return 1;
    	}
    	//------------Socket erstellen----------//
    	SOCKET client;
    	client = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    	//----------Addressinfo---------------//
    	SOCKADDR_IN addr;
    	addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    	addr.sin_port = htons(50000);
    	addr.sin_family = AF_INET;
    	//--------Port binden--------------//
    	/*rc = bind(client,(SOCKADDR *)&addr,sizeof(addr));
    
    	if(rc == SOCKET_ERROR){
    		cout << "bind(): Fehler " << GetLastError() << endl;
    		getchar();
    		WSACleanup();
    		return 1;
    	}
    
    	cout << "Port gebunden an " << ntohs(addr.sin_port) << endl;*/
    	//-------------Verbindung aufbauen------------//
    	rc = connect(client,(SOCKADDR *)&addr,sizeof(addr));
    
    	if(rc == SOCKET_ERROR){
    		cout << "connect(): Fehler " << GetLastError() << endl;
    		getchar();
    		WSACleanup();
    		return 1;
    	}
    	//---Senden von Daten-------------//
    	Sleep(3000);
    	char buffer[100] = "Hallo Welt";
    
    	int bsend = send(client,buffer,strlen(buffer),0);
    	if(bsend > 0){
    		buffer[bsend] = 0; //nullterminieren
    		cout << bsend << " bytes an Daten gesendet" << endl;
    		cout << "Nachricht: " << buffer << endl;
    	}
    	else if(bsend == SOCKET_ERROR){
    		cout << "send()_Error " << GetLastError() << endl;
    		getchar();
    		WSACleanup();
    		closesocket(client);
    		return 1;
    	}
    	//---Aufräumen--------//
    	WSACleanup();
    	getchar();
    
    	return 0;
    }
    


  • Beim Server die recv() Funktion erwartet als 3 Parameter die Größe des Buffers (2 Parameter).

    Die Funktion strlen gibt die Länge des strings zurück, bis zum ersten \0. Dein Char-Array fänge mit \0 an. Du sagst der Funktion recv also, dass der Buffer 0 Groß ist.

    Ersetze die Funktion strlen durch sizeof(). SIzeof gibt die Größe des Feldes zurück.

    Gruß Ombre



  • Es klappt, vielen Dank.


Log in to reply