进行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次认为发送失败。
- 增大
socket
的kernel 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/