设想在服务器能够复用关闭的Socket,但我在进行测试时总是出现错误,求各位兄弟帮忙解答!问题描述如下:
创建SOCKET并设置了
SO_REUSEADDR属性
WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED)
客户端请求连接(连接同时发送了数据包)
BOOL bSuccess = lpfnConnectEx( m_hSocket, (SockAddr*)&m_sockAddr, sizeof(SockAddr), m_writeIOData.szBuf, uLen, &dwSendLen, &m_writeIOData.overlapped );
工作线程
1、客户端正常断开时会向服务器发送断开连的接数据包
2、服务器收到断开请求后主动调用
lpfnDisconnectEx(m_hSocket, &m_writeIOData.overlapped, TF_REUSE_SOCKET, 0);
函数执行成功后调用AcceptEx想复用该m_hSocket
// Sleep(300); 如果Sleep才能每次设置成功,否则经常报10022错误
lpfnAcceptEx( listenSocket,
m_hSocket,
m_readIOData.szBuf,
m_readIOData.nBufLen-((sizeof(sockaddr_in) + 16) * 2),
sizeof(sockaddr_in) + 16,
sizeof(sockaddr_in) + 16,
&dwBytes,
&m_readIOData.overlapped ); //这里出错 事与愿违在lpfnAcceptEx时,偶尔能成功偶尔失败返回的错误代码为WSAEINVAL 10022
3、客户端收到数据包长度为0时同样会调用
lpfnDisconnectEx(m_hSocket, &m_writeIOData.overlapped, TF_REUSE_SOCKET, 0);
一个Socket的管理线程,当空闲队列的Socket少于指定数量时新创建一批WSASocket
一个IO工作线程
一个数据包处理线程
测试时客户端和服务端都仅分配一个WSASocket进行测试
我开始怀疑是线程同步创建Acceptex参数非法,但我反复确认后问题仍然出现
后来我
在DisconnectEx与Acceptex之间加Sleep(300)发现问题能得到解决(只是在客户端和服务端只有一个WSASocket进行了测试,我猜测DisconnectEx断开连接时需要时间,在这时间段内复用Socket时会失败。我设置SO_LINGER {1,0}、SO_DONTLINGER也不行。
希望各位能帮忙解答,先谢谢各位了!