Socket bleibt nach close noch offen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
XCooperation
Beiträge: 78
Registriert: 01.06.2005 15:05:37
Wohnort: Schrobenhausen
Kontaktdaten:

Socket bleibt nach close noch offen

Beitrag von XCooperation » 06.01.2006 19:24:17

Hallo,
ich schreibe gerade an einem kleinen Chatserver.
Mein Problem: Schließe ich den Socket mit close und beende das Programm mit exit(0), dann bleibt der Port noch eine Weile geöffnet. Das ist dumm, den in der Zeit kann man den Port natürlich nicht nochmal öffnen und das Programm funktioniert nicht...
Weiß jemand, wie ich den Socket sofort schließen kann?

Porgammcode:

Code: Alles auswählen

int main(int argc, char *argv[])
{
        SOCKET sockfd, new_fd;
        struct sockaddr_in my_addr;
        struct sockaddr_in their_addr;
        int sin_size;

        cout <<"Willkommen beim Chatserver!" <<endl;

        if( (sockfd = socket(AF_INET,SOCK_STREAM,0) ) == -1)
                err("Socket erstellen fehlgeschlagen!");

        //my_addr initialisieren
        my_addr.sin_family = AF_INET;
        my_addr.sin_port = htons(PORT);
        my_addr.sin_addr.s_addr = INADDR_ANY;
        bzero(&(my_addr.sin_zero),8);
        //Bind:
        if( bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr)) == -1)
        {
                perror("bind");
                err("bind fehlgeschlagen!");
        }
        //Listen:
        if( listen(sockfd, BACKLOG) == -1)
        {
                perror("listen");
                err("listen fehlgeschlagen!");
        }

        while(true)
        {
                sin_size = sizeof(their_addr);
                new_fd = accept(sockfd,(struct sockaddr*)&their_addr,
                                (socklen_t*)(&sin_size));
                if(new_fd==-1)
                {
                        perror("accept");
                        continue;
                }
                cout << "Server: Habe Verbindung von "
                        << inet_ntoa(their_addr.sin_addr) <<endl;

                char msg[]="Hallo Welt!\n";
                if( send(new_fd,msg,sizeof(msg)-1,0) == -1)
                        perror("send");
                close(new_fd);
                close(sockfd); //Wieso gehst du nicht zu %&$%/!!!!!!!!!
                cout <<"Auf Wiedersehen!" <<endl;
                exit(0);
        }
        close(sockfd);


        return 0;
}
Netstat gibt folgendes aus:

Code: Alles auswählen

Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 noname:4000             simonwa:4360            TIME_WAIT
Never trust a running system!
http://www.xenesis.net

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 06.01.2006 20:45:54

eigentlich schließt du den Socket sofort, das Problem liegt nur daran, daß du dem Client keine Chance gibst vorher die Verbindung zu schließen.
Das kannst du leicht testen, baue vor dem "close" ein "sleep(10)" ein. In dieser Zeit kannst du dann die Clientconnection schließen.

Gruß
gms

[edit]
Du könntest auch SO_REUSEADDR über setsockopt setzen, ist aber nicht wirklich empfehlenswert, weil es auch dann zu Problemen bein Neustart kommen kann.
Siehe: http://hea-www.harvard.edu/~fine/Tech/addrinuse.html
[/edit]

Antworten