【转】C# 网络连接中异常断线的处理:ReceiveTimeout, SendTimeout 及 KeepAliveValues(设置心跳)

 

在使用 TcpClient 网络连接中常常会发生客户端连接异常断开, 服务端需要设置检测手段进行这种异常的处理;

1、对于短连接,

通过对 Socket 属性ReceiveTimeout 和 SendTimeout 设置恰当的值, 使得程序在进行读/写时超时, 会产生 SocketException 异常, 通过检查这个异常并进行处理,来完成对异常断开的检测处理. 服务端连接处理代码如下:

Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, true);     //必须先启用接收超时选项,设置接收超时才有用。   

Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, true);     //必须先启用发送超时选项,设置发送超时才有用。        

Socket.ReceiveTimeOut=10000;//毫秒

Socket.SendTimeOut=10000;//毫秒

2、对于长连接

可以通过 Socket 中的心跳检测机制进行处理.

Socket的底层IO一般通过 WSAIoctl 函数进行设置. C# 中对此函数进行了封装, 即Socket.IOControl 方法.

publicint IOControl(

    IOControlCode ioControlCode,

    byte[] optionInValue,

    byte[] optionOutValue

)

其中第一个参数为 Socket IO 控制代码; 第二个参数为传入参数值, 第三个参数为传出值.

在Winsock 2 中定义了许多 Socket IO 控制类型 , 其中有一项: KeepAliveValues , 控制 TCP keep-alive 数据包的发送以及发送间隔。默认值为2个小时, 当间隔时间超过这个设定后, socket就会连续发送5次连接信号, 若客户端无回应, 则此 client socket会断开.

我们可以如下调整这个间隔时间:

newClient.Client.IOControl(IOControlCode.KeepAliveValues,BitConverter.GetBytes(120), null); // 设置为 2分钟.

以上即为2种网络异常连接断线检测的设置方法.

C#中,当进行网络连接操作时,加入超时判断的异常处理是为了确保程序能够处理因网络延迟或连接问题导致的长时间等待。通常情况下,可以使用`System.Net.Sockets`命名空间下的`Socket`类或`System.Net`命名空间下的`WebRequest`、`TcpClient`等类来进行网络操作,并设置超时时间来控制等待时长。以下是一个使用`Socket`类实现的示例代码: ```csharp using System; using System.Net; using System.Net.Sockets; public class NetworkExample { public static void ConnectWithTimeout(string host, int port, int timeout) { try { // 创建一个新的Socket对象 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 设置超时时间 socket.ReceiveTimeout = timeout; socket.SendTimeout = timeout; // 开始连接操作 socket.BeginConnect(host, port, new AsyncCallback(ConnectCallback), socket); // 防止超时前程序已经执行完其他逻辑,这里使用异步等待的方式来确保超时逻辑的执行 socket.WaitForConnectResult(); // 如果连接成功,则可以在这里处理连接后的事情 Console.WriteLine("Connected!"); // 发送和接收数据的代码... // 关闭Socket连接 socket.Shutdown(SocketShutdown.Both); socket.Close(); } catch (SocketException ex) { // 连接超时或其他Socket异常将被捕捉 if (ex.SocketErrorCode == SocketError.TimerExpire) { Console.WriteLine("连接超时。"); } else { Console.WriteLine($"发生错误: {ex.Message}"); } } catch (Exception ex) { // 其他可能的异常处理 Console.WriteLine($"发生错误: {ex.Message}"); } } private static void ConnectCallback(IAsyncResult ar) { Socket socket = (Socket)ar.AsyncState; try { // 结束异步连接操作 socket.EndConnect(ar); } catch (Exception ex) { // 如果连接失败,可以在这里处理异常 Console.WriteLine($"连接失败: {ex.Message}"); } } } // 使用示例: // NetworkExample.ConnectWithTimeout("www.example.com", 80, 5000); // 尝试连接到www.example.com的80端口,设置超时时间为5000毫秒 ``` 在这个示例中,我们通过`BeginConnect`方法启动了一个异步的连接操作,然后使用`WaitForConnectResult`方法等待连接完成或超时。我们还设置了`ReceiveTimeout`和`SendTimeout`来控制接收和发送操作的超时时间。如果超时发生,`SocketException`异常会被抛出,并且可以从中获取超时错误信息。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值