Прослушивание сокета не отвязывается в C ++ под Linux - PullRequest
11 голосов
/ 05 февраля 2010

У меня есть сокет, который прослушивает какой-то порт. Я посылаю сигнал SIGSTOP потоку, который ожидает на порту (используя accept), и завершаю его. затем я закрываю файл сокета, на котором я ждал. Но для следующего запуска моего проекта это не позволит мне снова прослушивать этот порт. Моя программа на C ++ под 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);

Спасибо.

Ответы [ 3 ]

22 голосов
/ 05 февраля 2010

Знаете ли вы, что сокеты, как правило, остаются в подвешенном состоянии в течение минуты или двух после того, как вы закончили их прослушивать, чтобы предотвратить передачу сообщений, предназначенных для предыдущего процесса? Он называется состоянием «TIME_WAIT».

Если вы хотите переопределить это поведение, используйте setsockopt , чтобы установить флаг SO_REUSEADDR для сокета перед его прослушиванием.

1 голос
/ 05 февраля 2010

Мне кажется, проблема в том, что вы неправильно закрыли сокет и / или вашу программу. Возможно, сокет все еще существует в ОС. проверьте это с помощью команды nestat -an. Вам также следует проверить, завершился ли ваш процесс. Если он правильно закончился, он должен был закрыть вашу розетку.

Что вы должны сделать, это:

  • прервите вашу нить сигналом.
  • при прерывании вашей нити следует аккуратно закрыть сокет до конца.
  • тогда вы можете чисто выйти из вашей программы.

my2cents

1 голос
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...