【问题标题】:Bind error while recreating socket重新创建套接字时绑定错误
【发布时间】:2011-08-01 08:30:18
【问题描述】:

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

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

【问题讨论】:

    标签: c sockets bind


    【解决方案1】:

    尝试用SO_REUSEADDR 调用setsockopt。参考:http://msdn.microsoft.com/en-us/library/ms740476(v=vs.85).aspx

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        在内核的某个地方,仍然有一些关于你以前的套接字的信息。告诉内核你愿意重用这个端口:

        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 以获得更详细的说明。

        【讨论】:

        • 在Solaris下使用char yes = 1
        【解决方案4】:

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

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

        close(client);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-08-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多