WinSock中关于阻塞接收/发送超时的一个BUG
2013-05-10 09:53
357 查看
在阻塞模型中,recvfrom和recv函数默认都是永久阻塞的,即没有数据到来和不发生错误的情况下函数的调用不会返回,但是可以调用setsockopt来设置阻塞时间。设置了合适的阻塞时间,可以让接收函数超时返回。
SO_RECVTIMEO即可控制接收函数的超时时间。例代码如下:
设定了超时时间后,recvfrom会定期返回并输出消息,如果这时候更改了系统时间,比如把系统时间改为昨天,那么recvfrom就不会立即返回了。把系统时间向后改比如改为明天则没有这个问题,但是再改回来又会出问题。推测是内部实现使用了绝对时间,而非相对时间才导致了这个问题。
阻塞IO模型中的UDP发送、TCP接收、TCP发送应该也存在类似的问题,不过我没有进行测试。linux平台不存在这个问题。
ps:我认为linux平台的做法是对的,这里应当使用相对时间。
int setsockopt( __in SOCKET s, __in int level, __in int optname, __in const char* optval, __in int optlen );
SO_RCVTIMEO | int | Receives time-out in milliseconds (available in the Microsoft implementation of Windows Sockets 2). |
SO_SNDTIMEO | int | Sends time-out in milliseconds (available in the Microsoft implementation of Windows Sockets 2). |
#include <WinSock2.h> #include <Windows.h> #include <stdio.h> #include <time.h> #pragma comment(lib, "Ws2_32.lib") int main() { WSADATA wd; WSAStartup(MAKEWORD(2, 2), &wd); SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); sockaddr_in sin; DWORD dwTime = 1000; sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons(0); if (SOCKET_ERROR == bind(sock, (sockaddr *)&sin, sizeof(sin)) || SOCKET_ERROR == setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&dwTime, sizeof(dwTime))) { return 0; } DWORD dwIndex = 0; while (TRUE) { char szBuffer[10000]; int len = sizeof(sin); int nRet = recvfrom(sock, szBuffer, sizeof(szBuffer), 0, (sockaddr *)&sin, &len); //本应至少每一秒输出一次,但是将系统时间更改到之前的时间后,此处不再输出 printf("%lu::%lu:%d\n", dwIndex++, time(NULL), nRet); } closesocket(sock); return 0; }
设定了超时时间后,recvfrom会定期返回并输出消息,如果这时候更改了系统时间,比如把系统时间改为昨天,那么recvfrom就不会立即返回了。把系统时间向后改比如改为明天则没有这个问题,但是再改回来又会出问题。推测是内部实现使用了绝对时间,而非相对时间才导致了这个问题。
阻塞IO模型中的UDP发送、TCP接收、TCP发送应该也存在类似的问题,不过我没有进行测试。linux平台不存在这个问题。
ps:我认为linux平台的做法是对的,这里应当使用相对时间。
相关文章推荐
- WinSock中关于阻塞接收/发送超时的一个BUG
- 设置TCP阻塞模式下的发送和接收函数超时时间
- Jmail的一个bug - 接收邮件时邮件的发送时间不对问题
- [http] WinInet发送或接收函数超时的bug & 解决办法
- Socket发送请求“超时”——接收数据方式引起的bug
- C#使用HttpWebRequest进行HTTP请求发送和接收的一些小结。(新增修复.NET4.0以下关于cookie的bug)
- 记录了一个关于smack 的bug,接收到xml但是监听无响应
- winsock编程如何设置发送与接收超时参数?
- 关于linux下的udp/tcp通信设置发送sendto/接收recvfrom信息超时的参数。解决通道堵塞问题。
- Indy接收邮件可能会出现的一个Bug
- Win10 UWP系列:关于错误 0x80073CF9及一个小bug的解决
- java中关于转义字符的一个bug
- windows 下socket recv 阻塞接收速度慢--send 阻塞发送慢
- 使用setsockopt()接口,设置TCP的接收与发送超时,Invalid argument错误问题
- windows 下socket recv 阻塞接收速度慢--send 阻塞发送慢
- 一个关于POLL的BUG,百思不得其解
- 关于重复接收NSNotificationCenter发送的通知的问题
- QQ超时不能刷新好友接收发送信息
- 关于javascript event flow 的一个bug详解
- 关于VC++中,两种自定义消息的发送与接收的方法实现进行说明。