在服务器终止后,再次打开会出现bind:address already in use解决方案

       首先,我们先声明:bind:address already in use的存在是合理的,在服务端终止之后,会有一个TIME_WAIT的状态,再次打开会出现:bind:address already in use。

       服务器端可以尽可能的使用REUSEADDR(在绑定之前尽可能调用setsockopt来设置REUSEADDR)套接字选项,这样就可以使得不必等待TIME_WAIT状态就可以重启服务器了,也就是说:TIME_WAIT状态还是存在的,但是不影响我们重新启动服务器。

       但是,当我们等上个2-4分钟后,然后在运行,就又没有这种情况了,很好解释,那只是因为在一定的时间内这个端口还被占用着,没有来的及释放,但是2-4分钟后,端口释放完毕,所以可以正常的运行这个程序了

      TIME_WAIT我方主动调用close()断开连接,收到对方确认后状态变为TIME_WAIT。TCP协议规定TIME_WAIT状态会一直持续2MSL(即两倍的分 段最大生存期),以此来确保旧的连接状态不会对新连接产生影响。处于TIME_WAIT状态的连接占用的资源不会被内核释放,所以作为服务器,在可能的情 况下,尽量不要主动断开连接,以减少TIME_WAIT状态造成的资源浪费。目前有一种避免TIME_WAIT资源浪费的方法,就是关闭socket的LINGER选项。但这种做法是TCP协议不推荐使用的,在某些情况下这个操作可能会带来错误。

       解决方案:

       当我们用:setsockopt和SO_REUSEADDR时:充分的减少了等待时间,在一次的通讯完毕,可以直接再次的运行这个程序,这样就不会出现上面如:bind:address already in use。

        程序如下:(在bind之前调用,提高端口的重用)

//调高端口的重用性
int on;
if(setsockopt(g_ptSerContext->iServerFd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(int))<<0)
{
	 perror("setsockopt error\n");
	 return 0;
}
if(bind(g_ptSerContext->iServerFd,(struct sockaddr *)&g_ptSerContext->SockAdd,\
 sizeof(g_ptSerContext->SockAdd))==-1)
{
        perror("bind error\n");
        return 0;
}

转自:https://blog.csdn.net/msdnwolaile/article/details/50743254

你可能感兴趣的:(解决方案)