send数据时遇到WSAEWOULDBLOCK

进行TCP网络编程, 用send()函数发送数据时,有时会遇到WSAEWOULDBLOCK错误, 这是个什么东东呢?

代码示例

    iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
    if (iResult == SOCKET_ERROR)
    {
       int nLastError = WSAGetLastError();
       if (WSAEWOULDBLOCK == nLastError )
       {
            ...
       }
        ...
    }

WSAEWOULDBLOCK

WSAEWOULDBLOCK
10035
Resource temporarily unavailable.
This error is returned from operations on nonblocking sockets that cannot be completed immediately, for example recv when no data is queued to be read from the socket.
It is a nonfatal error, and the operation should be retried later.
It is normal for WSAEWOULDBLOCK to be reported as the result from calling connect on a nonblocking SOCK_STREAM socket, since some time must elapse for the connection to be established.

WSAEWOULDBLOCK不是致命的错误,相关的操作应该在后续进行重试。

原因分析

WSAEWOULDBLOCK is not really an error but simply tells you that your send buffers are full.
This can happen if you saturate the network or if the other side simply doesn't acknowledge the received data. Take a look at the select() function, which allows you to wait until buffer space is available or a timeout occurs. There is also a way to bind a win32 event to a stream, which then allows its use with WaitForMultipleObjects in case you want to abort waiting early.

应该发送的window kernel buffer满了,需要有空闲时才能发送。

解决方法:

  • Sleep一段时间然后再进行发送
while(nRet == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK)
{
    Sleep(50);
    nRet = send(...);
}

这种思路最好加上次数的判断,比如超过20次认为发送失败。

  • 增大socketkernel buffer
SOCKET ConnectSocket = ...
...
int nRcvBufferLen = 1024*1024;
int nSndBufferLen = 4*1024*1024;
int nLen          = sizeof(int);
setsockopt(ConnectSocket, SOL_SOCKET, SO_RCVBUF, (char*)&nRcvBufferLen, nLen);
setsockopt(ConnectSocket, SOL_SOCKET, SO_SNDBUF, (char*)&nSndBufferLen, nLen);

进行音视频发送时,如果SO_SNDBUF设置过小,在网络环境不好的时候,会出现花屏的现象(数据来不及发送),网络环境好的时候则不会出现该现象。

References:

https://msdn.microsoft.com/en-us/library/ms740149(VS.85).aspx
https://msdn.microsoft.com/en-us/library/ms740668(v=vs.85).aspx#WSAEWOULDBLOCK
http://www.cnblogs.com/chengxin1982/archive/2009/12/24/1631067.html
http://stackoverflow.com/questions/14546362/how-to-resolve-wsaewouldblock-error
https://bobobobo.wordpress.com/2008/11/09/resolving-winsock-error-10035-wsaewouldblock/

你可能感兴趣的:(send数据时遇到WSAEWOULDBLOCK)