Verbindung trennen / Winsocks



  • Nach einer Verbindung möchte ich sie halt trennen, damit man eine neue aufbauen kann, momentan krieg ich noch fehler 10048. Ich hab es schon mit closesocket probiert, aber das klappte nicht.

    mfg.



  • Was hast du denn getan um sie zu öffnen? Vielleicht zeigst du mal ein bisschen code!



  • bool InitSocket(SOCKET* s)
    {
    	*s = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    	if ( *s == INVALID_SOCKET )
    	{
    		MessageBox(0,"Fehler: Socket konnte nicht erstellt werden!",0,0);
    		return false;
    	}
    	return true;
    }
    

    edit: Mööp! Sicher wundert ihr euch jetzt woher ich (flammenvogel) das weiß, aber joomoo ist gerade bei mir zu Hause mit seinem PC und hat das jetzt von meinem gepostet.



  • Also soweit du deinen Code gezeigt hast, ist doch alles ok. Lässt sich doch prima mit closesocket schließen? Was machst du denn sonst noch mit dem socket? Zeig das doch mal...



  • Auf der ServerSeite mache ich ein bind + listen + accept, auf der Client Seite ein connect. Dann Sende ich was mit recv und send. Dann will ich die Verbindung dannach abbauen (closesocket()). Allerdings wenn ich dann auf dem selben Socket und auf dem selben Port nochmal ein Socket erstelle kriege ich den WinSock Fehlercode 10048 (Port in use). Ich verstehe nicht warum ...

    Nochmal ein bisschen Code:

    void ServerSocket(void *dummy)
    {
     SOCKET *s = &DSocket;
    	//bind
    	SOCKET connected_socket;
    	int error_code;
    	sockaddr_in service;
    	service.sin_family = AF_INET;
    	service.sin_addr.s_addr = ADDR_ANY;
    	service.sin_port = htons( port );
    
    	if ( bind( *s, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) {
    		error_code = WSAGetLastError();
    		sprintf(buf, "WinSock Fehler: %i",error_code);
        MessageBox(0,buf,0,0);
        closesocket(*s);
        return;
    	}
    
    	//listen
    	if ( listen( *s, 1 ) == SOCKET_ERROR )
    	{
        MessageBox(0,"Error listening on socket",0,0);
    	}
    
    	//accept
      connected_socket = accept( *s, NULL, NULL );
    	*s = connected_socket;
    	Tfertig = true;
    }
    
    void ClientSocket(void *dummy)
    {
     SOCKET *s = &DSocket;
    	sockaddr_in clientService;
    
    	clientService.sin_family = AF_INET;
    	clientService.sin_addr.s_addr = inet_addr( Adresse );
    	clientService.sin_port = htons( port );
    
    	if ( connect( *s, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR)
    	{
      Tfertig = 2;
    	}
    	else
    	{
      Tfertig = true;
     }
    }
    

    (In flammenvogel alias joomoo)



  • Hmm, mir ist der Ablauf nicht ganz klar. Sieht das so aus ?
    S: BIND
    S: LISTEN
    S: ACCEPT <- Hier verbindet sich der Client und trennt die Verbindung wieder ?
    S: CLOSE

    C: CONNECT
    C: CLOSE

    An welcher Stelle dann das Problem auf ?



  • Nachdem die komplette Vernindung mit closesocket() beendet wurde, kann ich einfach keine neue auf dem Socket aufbauen. Oder habe ich deine Frage falsch verstanden?



  • Ruf mal zuerst shutdown() und dann closesocket() auf, u.U hilft das.

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/winsock_functions.asp

    MSDN schrieb:

    To assure that all data is sent and received on a connected socket before it is closed, an application should use shutdown to close connection before calling closesocket. For example, to initiate a graceful disconnect.



  • Irgendwie funktioniert das immer noch nicht richtig



  • Du verbindest dich mit dem Client (ClientSocket) zum Server (ServerSocket) und trennst dann beim ClientSocket die Verbindung ?
    Anschließend nimmt der ServerSocket keine weiteren Verbindungen vom ClientSocket an oder wie ?
    Wo kommt das Port-In-Use beim ClientSocket ?



  • Beim Server Socket...



  • Du verbindest also den ClientSocket mit dem ServerSocket und trennst dann die Verbindung vom ClientSocket aus und schließt den Socket vom Client und Server.
    Dann erzeugst du ServerSocket und ClientSocket neu und es geht nicht mehr ?



  • geeky (not@home) schrieb:

    Du verbindest also den ClientSocket mit dem ServerSocket und trennst dann die Verbindung vom ClientSocket aus und schließt den Socket vom Client und Server.
    Dann erzeugst du ServerSocket und ClientSocket neu und es geht nicht mehr ?

    Genau. Aber die Verbindung wird auf beiden Seiden mit closesocket() geschlossen, und nicht "vom ClientSocket aus", oder was meinst du damit?



  • Naja, ne echte Verbindung besteht ja nur, wenn Server-Socket den Client-Socket angenommen hat, wenn nun der Client-Socket geschlossen wird, ist ja praktisch keine Verbindung mehr da.

    Hmm, demnach scheint ja alles richtig gemacht zu werden, sehr merkwürdig.

    Was mich noch ein wenig irritiert:
    Wieso benutzt du bei listen(), bind(), etc. überall Pointer beim 1. Parameter ?
    Und was ist DSocket ?



  • geeky schrieb:

    Naja, ne echte Verbindung besteht ja nur, wenn Server-Socket den Client-Socket angenommen hat, wenn nun der Client-Socket geschlossen wird, ist ja praktisch keine Verbindung mehr da.

    Hmm, demnach scheint ja alles richtig gemacht zu werden, sehr merkwürdig.

    Was mich noch ein wenig irritiert:
    Wieso benutzt du bei listen(), bind(), etc. überall Pointer beim 1. Parameter ?
    Und was ist DSocket ?

    Bei listen(), blind(), etc. wird halt der Pointer auf DSocket (das ist einfach ein vorher definierter Socket) übergeben, ja etwas umständlich aber warum das so ist ist jetzt egal.

    Also send und recv funktionieren auch schon, und es klappt auch alles was wir wollen, nur man kann halt nicht ein zweites mal ServerSocket ausführen ohne ne Fehlermeldung zu kriegen, nachdem man schonmal eine Verbindung hatte.

    mfg.



  • Ist es denn dann beabsichtigt das DSocket beim Client und ServerSocket vorkommt ?
    Überschreibt sich das nicht gegenseitig oder sind Client und Socket jeweils in einer anderen Anwendung ?



  • geeky schrieb:

    Ist es denn dann beabsichtigt das DSocket beim Client und ServerSocket vorkommt ?
    Überschreibt sich das nicht gegenseitig oder sind Client und Socket jeweils in einer anderen Anwendung ?

    Welcher Socket ist in einer anderen Anwendung??? Versteh ich nicht ganz den zweiten Satz.

    Auf jeden fall sind beide funktionen in der gleich anwendung, und der client führt die clientsocket aus und der server die serversocket. Der DSocket überschneidet sich dann nicht weil er ja auf 2 PCs ist.

    mfg.



  • Den Socket der am Port lauscht schließt man ja nur am Ende des Programms.



  • Beim Nochmal-Angucken springt mir dieses ins Auge:

    //accept
      connected_socket = accept( *s, NULL, NULL );
        *s = connected_socket;
        Tfertig = true;
    

    Wieso weisst du *s den connected_socket zu ?
    Damit hast du den listen()-socket überschrieben und bei einem späteren closesocket(*s) schließt du nur die Client-Verbindung aber nicht den Listen-Socket.

    Edit: Im meinem letzten Post meinte ich "Client und Server" statt "Client und Socket", aber meine Frage wurde ja trotzdem beantwortet 😉



  • Wir (joomoo und ich)

    haben das jetzt in

    *s = accept( *s, NULL, NULL );
    

    geändert.

    Wie sollte der Code den sonst aussehen beim Server?

    EDIT: Es funktioniert mit dem geändertem Code auch nicht...



  • SOCKET *s = DSocket;
    

    Was ist DSocket für ein Socket?
    Du legst einen Pointer auf diesen Socket an und immer wenn du diesen Pointer benutzt greifst du also direkt auf diesen Socket zu.

    Ob du nun

    connected_socket = accept( *s, NULL, NULL );
        *s = connected_socket;
    

    schreibst oder

    *s = accept( *s, NULL, NULL );
    

    ist im Endeffekt egal.
    Ich denke das Problem liegt darin, dass du DSocket überschreibst und deshalb darauf beim zweiten Mal nicht zugegriffen werden kann.
    Das ist aber nur eine Vermutung, da ich nicht genau weiß was DSocket überhaupt für ein Socket ist.


Anmelden zum Antworten