Ошибка привязки при воссоздании сокета

A имеет следующий сокет слушателя:

int sd = socket(PF_INET, SOCK_STREAM, 0);

struct sockaddr_in addr;
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(http_port);
addr.sin_addr.s_addr = INADDR_ANY;

if(bind(sd,(sockaddr*)&addr,sizeof(addr))!=0)
{
    ...
}

if (listen(sd, 16)!=0)
{
    ...
}

int sent = 0;
for(;;) {
    int client = accept(sd, (sockaddr*)&addr, (socklen_t*)&size);
    if (client > 0)
    {
        ...
        close(client);
    }
}

Если использование

close(sd);

а затем при попытке воссоздать сокет с тем же кодом происходит ошибка привязки, и только через 30-60 секунд новый сокет создается успешно.

Есть ли способ создать или закрыть каким-нибудь классным способом, чтобы избежать ошибки привязки?


person spe    schedule 08.04.2011    source источник


Ответы (4)


Где-то в ядре все еще есть некоторая информация о вашем предыдущем сокете. Сообщите ядру, что вы все равно хотите повторно использовать порт:

int yes=1;
//char yes='1'; // use this under Solaris

if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) {
    perror("setsockopt");
    exit(1);
}

См. раздел bind() в руководстве beej по сетевому программированию. для более подробного объяснения.

person Philip    schedule 08.04.2011
comment
Используйте char yes = 1 под Solaris. - person user207421; 08.02.2018

Это ожидаемое поведение для сокетов TCP. Когда вы закрываете сокет, он переходит в состояние TIME_WAIT. Он будет принимать и отбрасывать пакеты для этого порта. Вам нужно установить опцию SO_REUSEADDR для немедленной повторной привязки.

person harper    schedule 08.04.2011

Вы не должны закрывать связанный сокет, а затем пытаться его воссоздать.

accept возвращает вновь созданный сокет только для этого соединения, его нужно закрыть. то есть: вы должны делать -

close(client);
person darklion    schedule 08.04.2011

Попробуйте позвонить setsockopt с помощью SO_REUSEADDR. См.: http://msdn.microsoft.com/en-us/library/ms740476(v=vs.85).aspx

person byte    schedule 08.04.2011