Webserver, socket immer schließen?



  • Guten Morgen,

    weiß nicht so genau, ob ich im korrekten Unterforum bzgl. meiner Frage unterwegs bin, schien mir aber am sinnvollsten...

    Meine Frage bezieht sich auf die Funktion closesocket(), der untere Code funktioniert nur, wenn der Socket immer wieder geschlossen wird. Muss das so sein? Bzw. wieso kann der Socket nicht permantent offen gehalten werden?

    int main()
    {
        struct sockaddr_in server, client;
        int sock, fd, len;
    
    	#ifdef _WIN32
    
    		short wVersionRequested;
    		WSADATA wsaData;
    		wVersionRequested = MAKEWORD (1, 1);
    		if (WSAStartup (wVersionRequested, &wsaData) != 0)
    		{
    			printf( "TCP konnte nicht initialisiert werden\n");
    			exit(1);
    		}
    	#endif
    
        sock = socket( PF_INET, SOCK_STREAM, 0);
    
        memset( &server, 0, sizeof (server));
        server.sin_family = AF_INET;
        server.sin_addr.s_addr = inet_addr(Standard_IP_Adresse);
        server.sin_port = htons(WEBSERVER_PORT);
    
        if (bind(sock, (struct sockaddr*)&server, sizeof( server)) < 0) 
    	{
            printf( "Bindung des Sockets nicht erfolgreich\n");
            exit(1);
        }
    
        listen(sock, 5);
    
        for (;;) 
    	{
            len = sizeof(client);
            fd = accept(sock, (struct sockaddr*)&client, &len);
            if (fd < 0) 
    		{
                perror("accept fehlgeschlagen!");
                exit(1);
            }
    
            serv_request(fd, fd);
    
            closesocket(fd);
        }
    }
    


  • In dem gezeigten Code macht es keinen Sinn, den Socket offen zu halten, weil die Socketvariable fd 'verloren' geht, wenn im nächsten Schleifendurchlauf ein anderer Client accepted wird.



  • seh ich ein, in der serv_request sind meine html-Dateien als Strings hinterlegt. Beim Starten des Servers wird im Browser die Seite nur dann angezeigt, wenn das Socket geschlossen wird, ansonsten lädt es nur unendlich lang.



  • http://www.willemer.de/informatik/unix/unprsock.htm

    hab hier was gefunden, dort steht:

    Jeder eröffnete Socket muss auch wieder geschlossen werden. Dies ist an sich eine Binsenweisheit.

    kann mir jemand vielleicht genauer erklären, wieso das so ist?



  • Eine Socketverbindung bei einem Webserver kann auch länger offen bleiben (s. HTTP/1.1, Connection: keep-alive). Das wird aber eben durch das Protokoll gesteuert. Wenn du dieses Protokoll also nicht korrekt umsetzt, dann scheitert es schon mal daran - das hat mit dem Socket dann nichts zu tun.

    Da HTTP/1.0 das erst gar nicht unterstützt, wirst du es auch hier nicht umsetzen können.

    Wenn du also mehrere Requests mit einer Verbindung bearbeiten willst, dann musst du:

    1. HTTP/1.1 nutzen
    2. Die Requests absolut korrekt behandeln und parsen
    3. in serv_request eine entsprechende Schleife sein

    Ansonsten ist es so, dass allgemein alle Ressourcen (egal ob Datei, Socket oder was auch immer) immer wieder geschlossen werden müssen. Das ist einfach guter und korrekter Stil. Du lässt ja auch nicht die Haustür offen, wenn du gehst.



  • Nachtrag:
    Beim Socket ist das Schließen der Verbindung noch etwas wichtiger, weil damit dem Server signalisiert wird, dass die Verbindung beendet ist. Er kann sie dann für andere Zwecke nutzen.

    Tut man das nicht, dann ist die Verbindung entweder klinisch tot und kann gar nicht mehr verwendet werden (schlechte Programmierung) oder sie wird nach einem entsprechenden Timeout vom Server eigenständig gekillt (kostet Zeit und die Verbindung ist länger blockiert als nötig).



  • Ok, wurde erfolgreich umgesetzt. Zwingend notwendig ist vor dem Headerfeld "Connection" das Feld "Content-Length", in dem die genaue Anzahl der Datenbytes enthalten sein muss.

    Vielen Dank!


Log in to reply