在TcpStream上究竟如何工作set_timeout()?

时间:2014-10-25 08:56:20

标签: tcp timeout rust

我正在使用TcpStream。我正在使用的基本结构是:

loop {
    if /* new data in the stream */ { /* handle it */ }
    /* do a lot of other stuff */
}

所以set_timeout()似乎是我需要的,但我对它是如何工作有点困惑。文档说:

  

此函数将为此流上的所有阻塞操作(包括读取和写入)设置超时。指定的超时是未来的相对时间(以毫秒为单位),之后操作将超时。这意味着必须定期重置超时以防止其过期。

所以我希望每次都要在检查新数据是否可用之前重置超时,否则我只会在一段时间之后才Err(TimeOut)

但似乎并非如此:实际上,如果我一劳永逸地设置一个非常低的超时(如10毫秒),那么循环就完全符合我的要求。如果存在,则返回新数据,如果没有,则返回Err(TimeOut)

我误解了文档吗?我可以安全地使用这种行为吗?

1 个答案:

答案 0 :(得分:1)

我原本期望它像套接字超时那样工作,就像你在大多数操作系统中作为套接字的属性一样,并且可以使用SO_TIMEOUT或类似的东西使用编程语言。使用此类套接字超时时,只要您在套接字上启动阻塞操作(如读取,写入,连接),就会启动计时器。操作将在时间范围内成功,或者由于超时而触发定时器并且操作失败。超时是套接字的属性而不是操作的属性,因此无需在每次操作之前再次设置它。

但根据文档Rust实现了一个完全不同的东西。如果我正确地解释文档,他们不会为每个操作设置超时,而是为套接字上的所有此类操作设置截止日期。也就是说,当计时器设置为10秒时,您可以在此时间内进行多次读取,但如果在10秒后仍然有读取活动,则它将被停止。

当一个用于处理其他语言的套接字超时时,这种行为不是预期的行为,看起来Rust开发人员对此(实验性)API有类似的反对意见。在https://github.com/rust-lang/rust/issues/15802中,他们建议将这些类型的函数重命名为set..timeoutset..deadline,以使名称反映行为。