重新创建套接字时绑定错误

时间:2011-04-08 08:53:01

标签: c sockets bind

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秒后成功创建新套接字。

有没有办法以一种很酷的方式创建或关闭以避免绑定错误?

4 个答案:

答案 0 :(得分:18)

在内核的某个地方,仍然有一些关于你之前插座的信息。告诉内核你还是愿意重新使用端口:

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

有关更详细的说明,请参阅the bind() section in beej's Guide to Network Programming

答案 1 :(得分:2)

这是TCP套接字的预期行为。关闭套接字时,它将进入TIME_WAIT状态。它将接受并丢弃此端口的数据包。您需要将SO_REUSEADDR选项设置为立即再次绑定。

答案 2 :(得分:1)

您不应该关闭绑定套接字,然后尝试重新创建它。

accept为该连接返回一个新创建的套接字,它是需要关闭的套接字。即:你应该做 -

close(client);

答案 3 :(得分:0)

尝试使用setsockopt致电SO_REUSEADDR。请参阅:http://msdn.microsoft.com/en-us/library/ms740476(v=vs.85).aspx