2010-02-05 8 views
10

Ich habe einen Socket, der auf einem Port abhört. Ich sende das Signal SIGSTOP an den Thread, der auf den Port wartet (mit accept) und beende es. dann schließe ich die fd der sockel, auf die ich gewartet habe. Aber für den nächsten Lauf meines Projekts erlaubt es mir nicht, wieder auf diesen Port zu hören. Mein Programm ist in C++ unter Linux. Was soll ich tun?Socket zuhören löst nicht in C++ unter Linux

Einige Teile meines Codes sind: Thread 1:

void* accepter(void *portNo) { 
int newsockfd; 
sockfd = socket(AF_INET, SOCK_STREAM, 0); 
if (sockfd < 0) { 
perror("ERROR opening socket"); 
} 
struct sockaddr_in server; 
bzero((char *) & server, sizeof (server)); 
server.sin_family = AF_INET; 
server.sin_port = htons(*(int*) portNo); 
server.sin_addr.s_addr = INADDR_ANY; 
if (bind(sockfd, (struct sockaddr *) & server, sizeof (struct sockaddr_in)) < 0) { 
perror("ERROR on binding"); 
} 

listen(sockfd, 50); 
while (true) { 
struct sockaddr_in client; 
socklen_t clientLen = sizeof (struct sockaddr_in); 
newsockfd = accept(sockfd, (struct sockaddr *) & client, &clientLen); 
if (accepterFlag) { 
    break; 
} 
if (getpeername(newsockfd, (sockaddr *) & client, &clientLen) == -1) { 
    perror("getpeername() failed"); 
} 
sem_wait(setSem); 
FD_SET(newsockfd, &set); 
if (maxFd < newsockfd) { 
    maxFd = newsockfd; 
} 
sem_post(setSem); 
} 

Thema 2:

listenerFlag = true; 
accepterFlag = true; 
sleep(1); 
pthread_kill(listenerThread, SIGSTOP); 
pthread_kill(accepterThread, SIGSTOP); 
close(sockfd); 
sem_wait(setSem); 
for (int i = 1; i <= maxFd; i++) { 
if (FD_ISSET(i, &set)) { 
    close(i); 
} 
} 
sem_post(setSem); 

Danke.

+0

Vielleicht versuchen, die fd des Sockets innerhalb des akzeptierenden Thread zu schließen, wie es beendet? –

+1

Sind Sie sicher, dass Sie 'SIGSTOP' senden möchten? Wird jemand später eine 'SIGCONT' senden? Ich wäre nicht überrascht, wenn Sockets nicht endlich geschlossen werden könnten, solange ein (gestoppter) Thread sich noch in einem 'accept'-Call auf diesem Socket befindet. (Sie sagten, Sie haben auch den Thread beendet, ich sehe das einfach nicht.) Ich weiß das. –

Antwort

21

Wussten Sie, dass Steckdosen typischerweise in einer Art Schwebezustand für eine Minute oder zwei gehalten werden, nachdem Sie auf sie fertig sind hören Kommunikation für den vorherigen Prozess zu Ihnen kommen soll zu verhindern? Es heißt der Status 'TIME_WAIT'.

Wenn Sie dieses Verhalten überschreiben möchten, verwenden Sie setsockopt, um das Flag SO_REUSEADDR für den Socket festzulegen, bevor Sie darauf warten.

+4

Überprüfen Sie auch SO_LINGER. http://www.developerweb.net/forum/archive/index.php/t-2982.html – jfawcett

+0

Ich wusste das in Java. Ist es das gleiche für C++? – Shayan

+3

Ja, es ist eher ein TCP-Ding als ein Sprachding, also gilt es überall. –

1

Ich denke, das Problem ist, dass Sie nicht richtig den Socket geschlossen haben und/oder Ihre Programmdauer Buchse wahrscheinlich immer noch in dem O. überprüfe es mit etwas wie nestat -an. Sie sollten auch prüfen, ob Ihr Prozess beendet wurde. Wenn es korrekt beendet wurde, sollte es Ihren Sockel geschlossen haben.

Was sollten Sie tun, ist:

  • Thread mit einem Signal unterbrechen.
  • Wenn der Thread unterbrochen wird, sollte die Buchse sauber vor dem Ende geschlossen werden.
  • dann können Sie sauber aus Ihrem Programm beenden.

my2cents,

+0

Bitte die bearbeitete Frage anzeigen. – Shayan

+0

Ok. Dann ist SO_REUSEADDR der Schlüssel :-) – neuro