套接字监听并没有在Linux下的C ++中取消绑定

时间:2010-02-05 16:18:35

标签: c++ linux sockets

我有一个侦听某个端口的套接字。 我将SIGSTOP信号发送到等待端口的线程(使用accept)并终止它。然后我关闭了我等待的套接字的fd。但是对于我的项目的下一次运行,它不允许我再次听那个端口。 我的程序是用linux下的C ++编写的。 我该怎么办?

我的代码的某些部分是: 线程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);
}

主题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);

谢谢。

3 个答案:

答案 0 :(得分:22)

您是否知道,在您完成对它们的监听后,套接字通常会在一两分钟内保持不变,以防止之前进程的通信进入您的网络?它被称为'TIME_WAIT'状态。

如果要覆盖该行为,请使用setsockopt在侦听套接字之前设置SO_REUSEADDR标志。

答案 1 :(得分:1)

答案 2 :(得分:1)

我认为问题是你没有正确关闭套接字和/或你的程序。套接字可能仍然存在于操作系统中。用nestat -an之类的东西来检查它。您还应该检查您的流程是否已退出。如果它已正确结束,它应该关闭你的套接字。

你应该做的是:

  • 用信号打断你的线程。
  • 中断时你的线程应该在结束前干净地关闭套接字。
  • 然后你可以干净地退出你的程序。

my2cents,