如何让TCP客户端无限等待服务器信号,避免20秒超时终止?
解决TcpClient接收文件时无限等待的问题
你的代码里await操作20秒就终止,是因为TcpClient或其NetworkStream的读取超时默认被设置为20秒,要实现无限等待,只需显式取消超时限制:
具体修改步骤
1. 设置NetworkStream的无限读取超时
在获取stream对象后,添加一行代码设置ReadTimeout为无限(Timeout.Infinite对应-1毫秒,即无超时):
IPAddress serverAddress = IPAddress.Parse("192.168.1.66"); const int serverPort = 7777; string filename = "test.txt"; using var client = new TcpClient(serverAddress.ToString(), serverPort); using var stream = client.GetStream(); // 添加这行:设置读取无限等待 stream.ReadTimeout = Timeout.Infinite; byte[] buf = new byte[65536]; await ReadBytes(sizeof(long)); long remainingLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt64(buf, 0)); using var file = File.Create(filename); while (remainingLength > 0) { int lengthToRead = (int)Math.Min(remainingLength, buf.Length); await ReadBytes(lengthToRead); await file.WriteAsync(buf, 0, lengthToRead); remainingLength -= lengthToRead; } async Task ReadBytes(int howmuch) { int readPos = 0; while (readPos < howmuch) { var actuallyRead = await stream.ReadAsync(buf, readPos, howmuch - readPos); if (actuallyRead == 0) throw new EndOfStreamException(); readPos += actuallyRead; } }
2. (可选)设置TcpClient的接收超时
你也可以直接设置TcpClient的ReceiveTimeout属性,效果一致:
using var client = new TcpClient(serverAddress.ToString(), serverPort); // 设置TcpClient接收超时为无限 client.ReceiveTimeout = Timeout.Infinite; using var stream = client.GetStream();
关键说明
Timeout.Infinite的值是-1,表示读取操作会一直等待,直到有数据可读或连接断开。- 如果服务器主动断开连接,
stream.ReadAsync会返回0字节,此时你的代码会抛出EndOfStreamException,这属于正常的连接终止,并非超时问题。 - 若后续需要手动取消等待,可结合
CancellationTokenSource,将CancellationToken传入ReadAsync的重载方法,实现可控的取消逻辑(无限等待场景下无需此操作)。
内容的提问来源于stack exchange,提问作者godless
相关产品推荐
相关产品推荐

