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

17

我拥有以下侦听器套接字:

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个回答

21
在内核中,仍然存在有关您先前套接字的某些信息。告诉内核你仍然愿意重复使用该端口:
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);
}

请参考《Beej网络编程指南》中的bind()部分,获取更详细的解释。


在Solaris下使用char yes = 1 - user207421

3

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


1

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

accept 返回一个新创建的套接字,仅用于该连接,它是需要关闭的。也就是说,您应该这样做 -

close(client);

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接