我想等待来自TcpClient
客户端的响应缓慢,但无论我如何配置它,都会在大约20秒后达到超时。这是我的尝试:
using (var client = new TcpClient { ReceiveTimeout = 9999999, SendTimeout = 9999999 })
{
await client.ConnectAsync(ip, port);
using (var stream = client.GetStream())
{
// Some quick read/writes happen here via the stream with stream.Write() and stream.Read(), successfully.
// Now the remote host is calculating something long and will reply if finished. This throws the below exception however instead of waiting for >20s.
var bytesRead = await stream.ReadAsync(new byte[8], 0, 8);
}
}
例外是IOException
:
无法从传输连接读取数据:连接 尝试失败,因为关联方没有正确回应 一段时间后,或建立连接失败,因为 连接主机未能响应。
...里面包含SocketException
:
连接尝试失败,因为连接方没有 在一段时间后正确回应,或建立连接 失败,因为连接的主机无法响应
SocketErrorCode
是TimedOut
。
20世纪seems to be an OS default on Windows但是,是否可以通过与TcpClient
进行交互来从托管代码覆盖它?或者我怎么能等待响应呢?
我也尝试过旧式BeginRead
- EndRead
方式,EndRead
也是如此。该问题也不是由Windows防火墙或Defender引起的。
答案 0 :(得分:1)
我想等待客户的响应缓慢
请注意,连接失败是很重要的。连接超时仅用于建立连接,连接应始终非常快。事实上,操作系统将代表一个应用程序接受连接,因此您只是在谈论数据包往返。 21秒应该足够了。
建立连接后,您只需删除ReceiveTimeout
/ SendTimeout
并使用异步读取即可永久等待。
答案 1 :(得分:0)
事实证明,远程主机没有及时响应,因此问题。让我详细说明,虽然这将是一个非常具体的解决方案,但也许对其他人也有用。
真正的问题不是超时本身,正如异常所示,而是后续Read()
次调用中抛出的异常显示:“现有连接被远程主机强行关闭”
远程主机没有故意关闭连接。相反,发生的事情是,当响应缓慢时,它实际上非常繁忙,以至于它也没有处理任何TCP流量。虽然本地主机在等待响应时没有明确发送任何内容,但这仍然是一个问题:本地主机尝试为远程主机的先前传输发送ACK。由于这些无法传递,本地主机确定远程主机“强行关闭”连接。
我从Wireshark查看流量时得到了线索(总是很好地试着看看表面下面的东西而不是猜测):很明显,当远程主机忙碌时它显示完整的无线电安静。同时,Wireshark展示了当地主持人进行的重传尝试,表明这是问题的背后。
因此无法在本地主机上实现解决方案,需要更改远程主机的行为。