源码:
DWORD WINAPI CServerSocket:: ListenThread(LPVOID lparam)
{
try
{
//加以下语句可消除Debug时出现afxwin1.inl报错
//该在Release时是不出现
//AFX_MANAGE_STATE(AfxGetStaticModuleState);
CServerSocket *pServerSocket=(CServerSocket *)lparam;
createSucceed=pServerSocket->Create(pServerSocket->Port); //第2次执行时在这里出现WSAEADDRINUSE,原因是端口被占用
(createSucceed0)
{
AfxMessageBox("_ListenTcpThread Create!"+pServerSocket->GetError(GetLastError));
-1;
}
listenSucceed=pServerSocket->Listen(10); //开始监听
(listenSucceed0)
{
AfxMessageBox("_ListenTcpThread Listen!"+pServerSocket->GetError(GetLastError));
-1;
}
CSocket recSo;
SOCKADDR_IN client;
iAddrSize=(client);
Succeed=pServerSocket->Accept(recSo,(SOCKADDR *)&client,&iAddrSize); //接受连接并取得对方IP
....
}
先是查了不少文章堆搞不明白状况家伙胡乱指点有说是要AfxSocketInit,有说换个端口就可以了!
问题是我这个端口是监听我随机换话远程Client哪里知道该找哪个来连接???
总算找到下面段文字把原理给说清楚了!解决办法也很清楚 !
我处理是退出线程的前做下SetSockOpt代码如下:
//停止服务监听
BOOL CServerSocket::StopServer
{
DWORD exitcode;
WaitForSingleObject(m_hServerThread,500);
//解决WSAEADDRINUSE解决办法 start
//加这几句可以解决:停止监听再重新开启监听出现Create语句发生WSAEADDRINUSE问题
//问题提示端口已经被占用
BOOL bDontLinger=FALSE;
this->SetSockOpt(SO_DONTLINGER,(const char *)&bDontLinger,(bDontLinger),SOL_SOCKET);
this->Close;
//解决WSAEADDRINUSE解决办法 end
(!GetExitCodeThread(m_hServerThread,&exitcode))
{
TerminateThread(m_hServerThread,exitcode);
}
m_hServerThread=NULL;
0;
}
为什么TCP关闭后端口会处于TIME_WAIT状态?
般来说tcp正常关闭需要 4个包比如a和b关闭连接a先给b发个finb会进行确认ack然后b也会发出fin当a接受到这个fin并发出最后个ack后就会处于time_wait状态这个时间长短跟操作系统有关般会在1-4分钟也就是两倍数据包(2msl)最大生存时间TCP主动关闭方采用TIME_WAIT主要是为了实现终止TCP全双工连接可靠性及允许老重复分节在网络中消逝等过了2msl(大约1~4分钟)后TIME_WAIT就会消失
所以说主动发起关闭连接方会进入time_wait状态这个时候进程所占用端口号不能被释放除非在你中用sockopt设置端口可重用(SOCK_REUSE)选项但这不是所有操作系统都支持解决TIME_WAIT办法我个人认为以下两种比较好:
1、禁用LINGER
//Socket API
BOOL bDontLinger=FALSE;
sockopt(m_,SOL_SOCKET,SO_DONTLINGER,(LPCTSTR)&bDontLinger,(BOOL));
close(s);
//MFC CAsyncSocket或者CSocket
BOOL bDontLinger=FALSE;
m_->SetSockOpt(SO_DONTLINGER,(const char *)&bDontLinger,(bDontLinger),SOL_SOCKET);
m_->Close;
最新评论