WinSock recv()超时:setsockopt()-设置值+半秒?

发布于 2024-11-12 21:16:59 字数 508 浏览 0 评论 0原文

我正在编写一个跨平台库,除其他外,它提供了一个套接字接口,在运行我的单元测试套件时,我注意到通过setsockopt()设置的超时有些奇怪: Windows 中,阻塞的 recv() 调用似乎始终比通过 SO_RCVTIMEO 选项指定的时间晚大约半秒(500 毫秒)返回。

我错过的文档中有对此有任何解释吗?搜索网络,我只能找到 对问题的其他参考 – 拥有 »Windows Sockets 的人可以吗 网络编程 « 作者:Bob Quinn 和 Dave Shute 帮我查找第 466 页吗?不幸的是,我现在只能运行我的测试 Windows Server 2008 R2,其他 Windows 版本上是否也存在同样的奇怪行为?

I am writing a cross-platform library which, among other things, provides a socket interface, and while running my unit-test suite, I noticed something strange with regard to timeouts set via setsockopt(): On Windows, a blocking recv() call seems to consistently return about half a second (500 ms) later than specified via the SO_RCVTIMEO option.

Is there any explanation for this in the docs I missed? Searching the web, I was only able to find a single other reference to the problem – could somebody who owns »Windows Sockets
Network Programming« by Bob Quinn and Dave Shute look up page 466 for me? Unfortunately, I can only run my test Windows Server 2008 R2 right now, does the same strange behavior exist on other Windows versions as well?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

只有一腔孤勇 2024-11-19 21:16:59

来自 Jones 和 Ohlund 的 Microsoft Windows 网络编程

SO_RCVTIMEO 最佳值

<小时>

  • 类型:int
  • 获取/设置:两者
  • Winsock 版本:1+
  • 描述:获取或设置超时值(以毫秒为单位)
    与接收数据有关
    套接字

<小时>

SO_RCVTIMEO 选项设置
接收阻塞的超时值
插座。超时值是
以毫秒为单位的整数,表示
Winsock接收函数需要多长时间
尝试时应该阻止
接收数据。如果您需要使用
SO_RCVTIMEO 选项,您使用
WSASocket函数创建
套接字,您必须指定
WSA_FLAG_OVERLAPPED 作为一部分
WSASocket 的 dwFlags 参数。
对任何 Winsock 的后续调用
接收函数(如recv、
recvfrom、WSARecv 或 WSARecvFrom)
仅在一定时间内阻塞
指定的。如果没有数据到达
那时,呼叫失败并显示
错误 10060(WSAETIMEDOUT)。如果
接收器操作确实超时
套接字处于不确定状态
且不应使用。

出于性能原因,此选项
在 Windows CE 2.1 中被禁用。如果你
尝试设置这个选项,它是
默默无视,没有失败
返回。以前版本的 Windows
CE确实实现了这个选项。

我认为其中的关键信息是:

如果您需要使用SO_RCVTIMEO选项并且您使用WSASocket
创建套接字的函数,您
必须将 WSA_FLAG_OVERLAPPED 指定为
WSASocket 的 dwFlags 参数的一部分

我希望这仍然有用:)

From Networking Programming for Microsoft Windows by Jones and Ohlund:

SO_RCVTIMEO optval


  • Type: int
  • Get/Set: Both
  • Winsock Version: 1+
  • Description : Gets or sets the timeout value (in milliseconds)
    associated with receiving data on the
    socket

The SO_RCVTIMEO option sets the
receive timeout value on a blocking
socket. The timeout value is an
integer in milliseconds that indicates
how long a Winsock receive function
should block when attempting to
receive data. If you need to use the
SO_RCVTIMEO option and you use the
WSASocket function to create the
socket, you must specify
WSA_FLAG_OVERLAPPED as part of
WSASocket's dwFlags parameter.
Subsequent calls to any Winsock
receive function (such as recv,
recvfrom, WSARecv, or WSARecvFrom)
block only for the amount of time
specified. If no data arrives within
that time, the call fails with the
error 10060 (WSAETIMEDOUT). If the
receiver operation does time out the
socket is in an indeterminate state
and should not be used.

For performance reasons, this option
was disabled in Windows CE 2.1. If you
attempt to set this option, it is
silently ignored and no failure
returns. Previous versions of Windows
CE do implement this option.

I'd think the crucial information in this is:

If you need to use the SO_RCVTIMEO option and you use the WSASocket
function to create the socket, you
must specify WSA_FLAG_OVERLAPPED as
part of WSASocket's dwFlags parameter

I hope this is still useful :)

赠我空喜 2024-11-19 21:16:59

我也有同样的问题。将使用

patchedTimeout = max ( unpatchedTimepit - 500, 1 )

使用 unpatchedTimepit == 850 对此进行测试

I am having the same problem. Going to use

patchedTimeout = max ( unpatchedTimepit - 500, 1 )

Tested this with the unpatchedTimepit == 850

擦肩而过的背影 2024-11-19 21:16:59

你的问题不在于rcv函数超时!

如果您的应用程序有一个 while 循环来检查和接收,只需放置一个 if 语句来检查接收缓冲区最后一个索引“\0”字符,以检查接收字符串是否结束。

通常,如果 rcv 函数仍在接收,则返回值是接收到的数据的大小。 size 可以用作缓冲区数组的最后一个索引。

   do{
       result = rcv(s,buf,len,0);
        if(buf[result] == '\0'){
           break;
        }
    }
    while(result > 0);

your problem is not in rcv function timeout!

if your application have a while loop to check and receive just put an if statement to check the receive buffer last index for '\0' char to check is the receiving string is ended or not.

typically if rcv function is still receiving return value is the size of received data. size can be used as last index of buffer array.

   do{
       result = rcv(s,buf,len,0);
        if(buf[result] == '\0'){
           break;
        }
    }
    while(result > 0);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文