使用Create出现WSAEADDRINUSE错误的解决办法
2013-06-30 20:58
302 查看
程序源码:
先是查了不少文章,一堆搞不明白状况的家伙胡乱指点,有的说是要AfxSocketInit(),有的说换个端口就可以了!
问题是我的这个端口是监听的,我随机换的话,远程的Client哪里知道该找哪个来连接?
总算找到下面的一段文字,把原理给说清楚了!解决办法也很清楚 !
我的处理是,退出线程之前做一下SetSockOpt,代码如下:
为什么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的办法我个人认为以下两种比较好:
DWORD WINAPI CServerSocket:: ListenThread(LPVOID lparam) { try { //加以下语句可消除Debug时出现的afxwin1.inl的报错 //该错误在Release时是不出现的 //AFX_MANAGE_STATE(AfxGetStaticModuleState()); CServerSocket *pServerSocket=(CServerSocket *)lparam; int createSucceed=pServerSocket->Create(pServerSocket->intPort); //第2次执行时在这里出现WSAEADDRINUSE错误,原因是端口被占用 if(createSucceed==0) { AfxMessageBox("_ListenTcpThread Create错误!"+pServerSocket->GetError(GetLastError())); return -1; } int listenSucceed=pServerSocket->Listen(10); //开始监听 if(listenSucceed==0) { AfxMessageBox("_ListenTcpThread Listen错误!"+pServerSocket->GetError(GetLastError())); return -1; } CSocket recSo; SOCKADDR_IN client; int iAddrSize=sizeof(client); int intSucceed=pServerSocket->Accept(recSo,(SOCKADDR *)&client,&iAddrSize); //接受连接并取得对方IP .... } |
问题是我的这个端口是监听的,我随机换的话,远程的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,sizeof(bDontLinger),SOL_SOCKET); this->Close(); //解决WSAEADDRINUSE错误的解决办法 end if(!GetExitCodeThread(m_hServerThread,&exitcode)) { TerminateThread(m_hServerThread,exitcode); } m_hServerThread=NULL; return 0; } |
一般来说,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(); |
相关文章推荐
- 使用Genymotion调试出现错误INSTALL_FAILED_CPU_ABI_INCOMPATIBLE解决办法
- 使用Genymotion调试出现错误INSTALL_FAILED_CPU_ABI_INCOMPATIBLE解决办法
- 使用FindControl出现未将对象引用设置到对象的实例 错误的解决办法
- 使用px4编译代码时出现“no module names site”错误的解决办法
- 使用Genymotion调试出现错误INSTALL_FAILED_CPU_ABI_INCOMPATIBLE解决办法
- 使用Genymotion调试出现错误INSTALL_FAILED_CPU_ABI_INCOMPATIBLE解决办法
- 使用Genymotion调试出现错误INSTALL_FAILED_CPU_ABI_INCOMPATIBLE解决办法
- 使用Genymotion调试出现错误INSTALL_FAILED_CPU_ABI_INCOMPATIBLE解决办法
- MyEclipse Servers视窗出现“Could not create the view: An unexpected exception was thrown”错误解决办法
- 使用Genymotion调试出现错误INSTALL_FAILED_CPU_ABI_INCOMPATIBLE解决办法
- ubuntu上在使用c/c++连接mysql时,出现undefined reference错误解决办法
- 使用Genymotion调试出现错误INSTALL_FAILED_CPU_ABI_INCOMPATIBLE解决办法
- 使用git clone出现SSL routines:SSL3_GET_SERVER_CERTIFICATE错误的一种解决办法
- 关于使用Tomcat服务器出现413错误的解决办法(Request Entity Too Large)
- 问题解决_(转载)在VisualStudio 2012上使用MVC3出现错误的解决办法
- 使用Genymotion调试出现错误INSTALL_FAILED_CPU_ABI_INCOMPATIBLE解决办法
- AS使用第三方包出现错误(Duplicate files copied in APK META-INF/NOTICE)的解决办法
- 使用Genymotion调试出现错误INSTALL_FAILED_CPU_ABI_INCOMPATIBLE解决办法
- 使用Genymotion调试出现错误INSTALL_FAILED_CPU_ABI_INCOMPATIBLE解决办法
- 关于 JDeveloper 出现 unable to create an instance of the java virtual machine 错误的解决办法