Socket listen не отвязывает в С++ под Linux
У меня есть сокет, который прослушивает какой-то порт.
Я посылаю сигнал SIGSTOP в поток, который ждет порт (с помощью accept) и завершает его. то я закрываю fd сокета, который я ждал. Но для следующего запуска моего проекта это не позволяет мне снова слушать этот порт.
Моя программа находится в С++ под Linux.
Что мне делать?
Некоторые части моего кода:
Тема 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);
Спасибо.
Ответы
Ответ 1
Знаете ли вы, что сокеты обычно хранятся в какой-то неопределенности в течение минуты или двух после того, как вы закончили прослушивать их, чтобы предотвратить обмен сообщениями, предназначенными для предыдущего процесса? Он называл состояние "TIME_WAIT".
Если вы хотите переопределить это поведение, используйте setsockopt, чтобы установить флаг SO_REUSEADDR в гнездо перед его прослушиванием.
Ответ 2
Смотрите: Использование SO_REUSEADDR - Что происходит с ранее открытым сокетом?
Ответ 3
Я думаю, проблема в том, что вы неправильно закрыли сокет и/или вашу программу. Возможно, сокет все еще существует в ОС. проверьте его с чем-то вроде nestat -an. Вы также должны проверить, вышел ли ваш процесс. Если он был правильно закончен, он должен был закрыть ваш сокет.
Что вам нужно сделать:
- Прервать поток с сигналом.
- когда прерван ваш поток, должен чисто закрыть розетку до конца.
- тогда вы можете полностью выйти из своей программы.
my2cents,