RCSocketResult RCAsyncSocket::Send(const char* pBuff, int32_t nLen, int32_t& nLenSent, DWORD dwTimeOut)
{
m_nLastError = 0;
int32_t bytesSent = 0;
int32_t sendLeft = nLen;
nLenSent = 0;
HANDLE arrHandles[3];
int32_t waitCount = (m_breakEvent != NULL) ? 3 : 2;
arrHandles[0] = m_eventNet.GetEvent();
arrHandles[1] = m_eventStop.GetEvent();
arrHandles[2] = m_breakEvent;
do
{
bytesSent = send(m_hSocket, pBuff, sendLeft, 0);;
if (bytesSent == SOCKET_ERROR)
{
m_nLastError = WSAGetLastError();
if (m_nLastError != WSAEWOULDBLOCK)
{
//WRITE_DEBUG_LOG(RCMOBILE_MODDULE_CONNECT_GUID, _T(" RCAsyncSocket::Send Error 01 with error code %d"), m_nLastError);
return RC_SOCKET_SOCKERR;
}
bytesSent = 0;
DWORD dwWaitRes = WaitForMultipleObjects(waitCount, arrHandles, FALSE, dwTimeOut);
if (dwWaitRes == WAIT_OBJECT_0 + 1 || dwWaitRes == WAIT_OBJECT_0 + 2)
{
m_nLastError = WSAGetLastError();
//WRITE_DEBUG_LOG(RCMOBILE_MODDULE_CONNECT_GUID, _T(" RCAsyncSocket::Send Error 02 Abort"));
return RC_SOCKET_ABORTED;
}
else if (dwWaitRes != WAIT_OBJECT_0)
{
m_nLastError = WSAGetLastError();
//WRITE_DEBUG_LOG(RCMOBILE_MODDULE_CONNECT_GUID, _T(" RCAsyncSocket::Send Error 03 TimeOut"));
return RC_SOCKET_TIMEDOUT;
}
WSANETWORKEVENTS netEvents;
if (WSAEnumNetworkEvents(m_hSocket, m_eventNet.GetEvent(), &netEvents) != 0)
{
m_nLastError = WSAGetLastError();
//WRITE_DEBUG_LOG(RCMOBILE_MODDULE_CONNECT_GUID, _T(" RCAsyncSocket::Send Error 04 WSAEnumNetworkEvents error with ErrorCode %d"), m_nLastError);
return RC_SOCKET_SOCKERR;
}
if ((netEvents.lNetworkEvents & FD_CLOSE) == FD_CLOSE)
{
m_nLastError = WSAGetLastError();
//WRITE_DEBUG_LOG(RCMOBILE_MODDULE_CONNECT_GUID, _T(" RCAsyncSocket::Send Error 05 FD_CLOSE"));
return RC_SOCKET_ABORTED;
}
if ((netEvents.lNetworkEvents & FD_WRITE) == FD_WRITE)
{
if (netEvents.iErrorCode[FD_WRITE_BIT] != 0)
{
m_nLastError = WSAGetLastError();
//WRITE_DEBUG_LOG(RCMOBILE_MODDULE_CONNECT_GUID, _T(" RCAsyncSocket::Send Error 06 FD_WRITE_BIT error"));
return RC_SOCKET_SOCKERR;
}
}
}
nLenSent += bytesSent;
pBuff += bytesSent;
sendLeft -= bytesSent;
}
while (sendLeft > 0);
return RC_SOCKET_SUCCESS;
}
RCSocketResult RCAsyncSocket::Recv(char* pBuff, int32_t nLen, int32_t& nLenReceived, DWORD dwTimeOut)
{
m_nLastError = 0;
HANDLE arrHandles[3];
int32_t waitCount = (m_breakEvent != NULL) ? 3 : 2;
arrHandles[0] = m_eventNet.GetEvent();
arrHandles[1] = m_eventStop.GetEvent();
arrHandles[2] = m_breakEvent;
int32_t recvLeft = nLen;
int32_t bytesRecv = 0;
nLenReceived = 0;
do
{
bytesRecv = ::recv(m_hSocket, pBuff, recvLeft, 0);
if (bytesRecv == 0)
{
m_nLastError = WSAGetLastError();
WRITE_ERROR_LOG(RCMOBILE_MODDULE_CONNECT_GUID, _T(" RCAsyncSocket::Recv Error 01 connection closed"));
return RC_SOCKET_ABORTED;
}
else if(bytesRecv == SOCKET_ERROR)
{
m_nLastError = WSAGetLastError();
if (m_nLastError != WSAEWOULDBLOCK)
{
WRITE_ERROR_LOG(RCMOBILE_MODDULE_CONNECT_GUID, _T(" RCAsyncSocket::Recv Error 02 with error code %d"), m_nLastError);
return RC_SOCKET_SOCKERR;
}
bytesRecv = 0;
DWORD dwWaitRes = WaitForMultipleObjects(waitCount, arrHandles, FALSE, dwTimeOut);
if (dwWaitRes == WAIT_OBJECT_0 + 1 || dwWaitRes == WAIT_OBJECT_0 + 2)
{
WRITE_ERROR_LOG(RCMOBILE_MODDULE_CONNECT_GUID, _T(" RCAsyncSocket::Recv Error 03 connection Abort"));
return RC_SOCKET_ABORTED;
}
else if (dwWaitRes != WAIT_OBJECT_0)
{
WRITE_ERROR_LOG(RCMOBILE_MODDULE_CONNECT_GUID, _T(" RCAsyncSocket::Recv Error 04 recv timeout"));
return RC_SOCKET_TIMEDOUT;
}
WSANETWORKEVENTS myNetEvents;
if (::WSAEnumNetworkEvents(m_hSocket, m_eventNet.GetEvent(), &myNetEvents) != 0)
{
WRITE_ERROR_LOG(RCMOBILE_MODDULE_CONNECT_GUID, _T(" RCAsyncSocket::Recv Error 05 with error code %d"), m_nLastError);
m_nLastError = WSAGetLastError();
return RC_SOCKET_SOCKERR;
}
if ((myNetEvents.lNetworkEvents & FD_READ) == FD_READ)
{
if (myNetEvents.iErrorCode[FD_READ_BIT] != 0)
{
m_nLastError = WSAGetLastError();
WRITE_ERROR_LOG(RCMOBILE_MODDULE_CONNECT_GUID, _T(" RCAsyncSocket::Recv Error 06 with error FD_READ_BIT %d"), myNetEvents.iErrorCode[FD_READ_BIT]);
return RC_SOCKET_SOCKERR;
}
continue;
}
if ((myNetEvents.lNetworkEvents & FD_CLOSE) == FD_CLOSE)
{
//WRITE_DEBUG_LOG(RCMOBILE_MODDULE_CONNECT_GUID, _T(" RCAsyncSocket::Recv Error 07 connection receive FD_CLOSE"));
continue;
}
}
nLenReceived += bytesRecv;
recvLeft -= bytesRecv;
pBuff += bytesRecv;
}
while (recvLeft > 0);
return RC_SOCKET_SUCCESS;
}
关键在于,错误码是WSAEWOULDBLOCK时,设置当前发送或者接受的字节数为0,然后用
WSAEnumNetworkEvents检测网络事件。
本文探讨了在使用send和recv进行非阻塞网络通信时,如何妥善应对WSAEWOULDBLOCK错误码,并介绍如何正确设置超时机制。
3954

被折叠的 条评论
为什么被折叠?



