11

I have a socket that listens on some port. I send the SIGSTOP signal to the thread that waits on the port (using accept) and terminate it. then I close the fd of the socket that I waited on. But for the next run of my project it doe's not allow me to listen on that port again. My program is in C++ under linux. What should I do?

Some parts of my code are: 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);
}

Thread 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);

Thank you.

Shayan
  • 2,758
  • 7
  • 36
  • 55
  • Maybe try closing the fd of the socket inside the accepting thread as it's terminating? – Daniel Bingham Feb 05 '10 at 16:24
  • 1
    Are you sure you mean to send `SIGSTOP`? Is anyone going to send a `SIGCONT` later? I wouldn't be surprised if sockets could not finally be closed as long as some (stopped) thread is still inside an `accept` call on that socket. (You said you also terminated the thread, I just don't see that.) – Christopher Creutzig Feb 05 '10 at 16:45

2 Answers2

24

Did you know that sockets are typically kept in a kind of limbo for a minute or two after you've finished listening on them to prevent communications intended for the previous process coming to yours? It's called the 'TIME_WAIT' state.

If you want to override that behaviour use setsockopt to set the SO_REUSEADDR flag against the socket before listening on it.

Colin Newell
  • 3,073
  • 1
  • 22
  • 36
1

I think the problem is that you have not properly closed the socket and/or your program.The socket probably still exists in the OS. check it with something like nestat -an. You should also check if your process has exited. If it has correctly ended, it should have closed your socket.

What you should do is :

  • interrupt your thread with a signal.
  • when interrupted your thread should cleanly close the socket before the end.
  • then you can cleanly exit from your program.

my2cents,

neuro
  • 14,948
  • 3
  • 36
  • 59