You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C# Socket/TcpClient中延长连接超时阈值?

问题描述

我用Socket/TcpClient实现了客户端与服务器的连接,连接建立后双方能正常收发数据,服务器发数据客户端会回复,这个状态能维持13分钟。但13分钟后出现错误:

Connection timed out. A connection attempt failed because the connected party did not properly respond after a period of time, or the established connection failed because the connected host has failed to respond.

对应错误码 WSAETIMEDOUT 10060,确认是连接超时问题。想提高连接超时阈值延长连接时长,试了一些Socket选项,但不确定正确配置项,相关代码如下:

/*using Socket*/
var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);           
client.Connect(IPAddress.Parse("10.10.10.120"), 5000);

/*using TcpClient*/
var client1 = new TcpClient();  
client1.Connect(IPAddress.Parse("10.10.10.120"), 5000);
            
////which option should be choose in this case
//client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);          
//client.NoDelay = true; 
//client.SendTimeout = 180000; 
//client.ReceiveTimeout = 180000;  
//client.LingerState = new LingerOption(true, 180);
//client.Ttl = 42;
//client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.ReuseAddress, true);
//client.Poll(180000000, SelectMode.SelectRead);
//client.Poll(180000000, SelectMode.SelectWrite);
解决方案

问题核心是长时间无数据交互时,中间网络设备(如路由器、防火墙)主动断开了空闲连接,13分钟是这类设备的典型超时窗口。以下是针对性配置方案:

1. 启用TCP KeepAlive(最关键)

TCP KeepAlive是维持空闲连接的标准机制,会定期发送探测包,让中间设备认为连接处于活跃状态。

Socket方式配置

var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 启用KeepAlive基础开关
client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
// 配置KeepAlive参数(Windows系统需通过Tcp层级设置)
const int keepAliveTime = 600000; // 首次探测前的空闲时长(10分钟,单位毫秒)
const int keepAliveInterval = 30000; // 探测间隔(30秒,单位毫秒)
byte[] keepAliveValues = new byte[12];
BitConverter.GetBytes((int)1).CopyTo(keepAliveValues, 0);
BitConverter.GetBytes(keepAliveTime).CopyTo(keepAliveValues, 4);
BitConverter.GetBytes(keepAliveInterval).CopyTo(keepAliveValues, 8);
client.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveInterval, keepAliveValues);

client.Connect(IPAddress.Parse("10.10.10.120"), 5000);

TcpClient方式配置

TcpClient需通过底层Socket配置:

var client1 = new TcpClient();
// 启用KeepAlive基础开关
client1.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
// 配置参数
const int keepAliveTime = 600000;
const int keepAliveInterval = 30000;
byte[] keepAliveValues = new byte[12];
BitConverter.GetBytes((int)1).CopyTo(keepAliveValues, 0);
BitConverter.GetBytes(keepAliveTime).CopyTo(keepAliveValues, 4);
BitConverter.GetBytes(keepAliveInterval).CopyTo(keepAliveValues, 8);
client1.Client.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveInterval, keepAliveValues);

client1.Connect(IPAddress.Parse("10.10.10.120"), 5000);

2. 其他选项的作用(无需修改或无关)

  • NoDelay = true:禁用Nagle算法,适合小数据包实时传输,但和连接超时无关。
  • SendTimeout/ReceiveTimeout:控制单次发送/接收操作的超时时间,不是连接整体的空闲超时,设置这个不会延长连接存活时间。
  • LingerState:控制关闭连接时是否等待未发送数据,和维持连接无关。
  • Ttl:设置IP数据包的生存时间,不影响连接超时。
  • ReuseAddress:允许端口复用,和连接存活无关。
  • Poll():是主动检测连接状态的方法,不是配置项,不能解决自动超时问题。

额外说明

  • KeepAlive参数需根据网络环境调整:首次探测时间建议设为小于中间设备的超时时间(比如比13分钟短,设10分钟),探测间隔设为30-60秒,确保中间设备持续收到活跃信号。
  • 若服务器端未配置KeepAlive,需同步配置,避免单方面探测不被响应。

内容的提问来源于stack exchange,提问作者Headshot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 20:24:52