开发一个小巧而稳定的Socket Client(C#)

我们在上一篇文章中介绍了Socket Server的开发,这一篇介绍Socket Client的开发。相对于服务端,客户端的启停更加灵活,更需要处理重连的问题。

带超时功能的连接

不知道为什么,经过这么多版的迭代,Socket连接依然不支持超时功能。如果网络无法连接,Socket连接会尝试连接30秒左右,这一般都不符号实际需求。

在最新版的Soekt中,加入了带CancellationToken参数的异步连接方法ConnectAsync,可以帮助我们实现连接超时功能。代码如下所示:

CancellationTokenSource cts = new CancellationTokenSource();
cts.CancelAfter(3000);//假设只尝试连接3秒
try
{
    await ClientSocket.ConnectAsync(AddrEndPoint, cts.Token);
    //连接成功
}
catch
{
    //连接失败
}

断网重连的时机

如果网络本是好的,断开连接只是偶发性的因素引起,那么断开连接之后马上重连也未尝不可。但实际上断开连接时网络很可能不是好的。有可能物理链路断开了,有可能服务端宕机了,无论是哪种情况,我们都要等网络再次连通之后再去连接,否则就会消耗大量的资源。

一个比较好的方法是逐渐增加重连等待时间,在超过某个阈值后保持稳定。例如等待时间可以是一个这样的序列:1,2,3,5,10,20,30,50,50,50,50

检测连接断开

使用Socket.Connected去检测Socket是否连接是行不通的,可以使用下面的方法:

private bool IsConnected()
{
    try
    {
        bool success1 = !InnerSocket.Poll(1000, SelectMode.SelectRead);
        bool success2 = InnerSocket.Connected;
        return success1 && success2;
    }
    catch
    {
        return false;
    }
}

上面的方法实际上也是一个发送然后检查接收的过程,如果我们的程序本身就是不断发送,然后接收的,那没有必要通过上面的方法浪费资源。可以使用心跳机制,当服务端在一段时间内没有应答,即判定为断开连接,可以尝试重连。

关闭

如果需要关闭Socket,需要先断开连接,然后再关闭。由于每一步都会抛出异常,需要捕抓每一步产生的异常。

try
{
    if (ClientSocket.Connected)
    {
        ClientSocket.Disconnect(false);
    }
}
catch (Exception ex)
{
    //
}
try
{
    ClientSocket.Close();
}
catch (Exception ex)
{
    //
}

ClientSocket = null;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值