Socket连接返回的WSAEADDRINUSE错误的解决方法

在客服端断开TCP连接后,又继续连接服务器是会连接失败,返回错误标识: WSAEADDRINUSE(=10048),标识服务器端端口正在被使用。为什么了? 因为客户端断开后,服务器端没有断开(即断开TCP连接的4次握手只完成了2次,所以服务器端还未真正断开),更具体的原因以及解决方法如下(如下内容转载自:http://c.chinaitlab.com/ccjq/773134.html):


  为什么TCP关闭后端口会处于TIME_WAIT状态?

    一般来说,tcp正常关闭需要四个包。比如a和b关闭连接,a先给b发一个fin,b会进行确认ack,然后b也会发出fin,当a接受到这个fin,并发出最后一个ack后,就会处于time_wait状态。这个时间长短跟操作系统有关,一般会在1-4分钟,也就是两倍的数据包(2msl)最大生存时间。TCP主动关闭方采用TIME_WAIT主要是为了实现终止TCP全双工连接的可靠性及允许老的重复分节在网络中消逝,等过了2msl(大约1~4分钟)后TIME_WAIT就会消失。

    所以说,主动发起关闭连接的一方会进入time_wait状态,这个时候,进程所占用的端口号不能被释放。除非在你的程序中用setsockopt设置端口可重用(SOCK_REUSE)的选项,但这不是所有操作系统都支持的,解决TIME_WAIT的办法我个人认为以下两种比较好:


1、禁用LINGER
//Socket API
BOOL bDontLinger=FALSE;
setsockopt(m_socket,SOL_SOCKET,SO_DONTLINGER,(LPCTSTR)&bDontLinger,sizeof(BOOL));
closesocket(s);

//MFC CAsyncSocket或者CSocket
BOOL bDontLinger=FALSE;
m_socket->SetSockOpt(SO_DONTLINGER,(const char *)&bDontLinger,sizeof(bDontLinger),SOL_SOCKET);
m_socket->Close();


你可能感兴趣的:(C++,MFC)