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

有一些现成的Socket服务端可以供我们使用,例如SuperSocket、FastSocket,甚至是DotNetty。DotNetty是很庞大的,另外两个会小一些。但如果我们并不是要做一个多强大的服务器,只是想简单收发一下数据,能自动重连,能稳定运行就够,那我们不必使用上面的第三方库。

最基础的服务端模板

下面的代码实现了最基础的服务端功能:

ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ServerSocket.Bind(IP,端口);
ServerSocket.Listen(20);
ServerSocket.BeginAccept(AcceptCallback, ServerSocket);

private void AcceptCallback(IAsyncResult asyncresult)
{
    //处理客户端连接
}

但是在实际的使用过程中,会出现各种问题,主要就是网络中断之后发送、接收、连接会出现的异常。只要我们把这些异常处理好,Socket Server就能稳定运行。

创建、绑定和侦听

Socket的创建、绑定和侦听,每一步都有可能抛出异常。但是对于一个正常的网络来说,上述步骤出现异常是非常罕见的。而且一旦出现异常,说明计算机的网络存在问题,要么是硬件,要么是网络配置,这些都需要在程序的外部去处理,不是重启程序多试几次就能解决的。所以对于上述步骤,如果出现异常,可以直接停止程序,让用户处理好网络问题之后再去启动。

客户端管理

我们在AcceptCallback函数里,可以得到客户端对象。如果要跟客户端通信,必须依靠这些对象。如果不是用一次丢一次,就需要把这些对象保存起来。在Accept的时候添加客户端,在Close的时候删除所有客户端,在收发数据的过程中,判断客户端是否仍连接,把已经没有连接的客户端删除。

由于对客户端的处理是一个异步操作,有必要处理一些线程冲突问题。

(1)可以使用ConcurrentBag这些线程安全容器去存放客户端。

(2)或者使用List这些线程不安全的容器存放,但是在操作的前后加上线程锁:

Monitor.Enter(LockObject);
//操作
Monitor.Exit(LockObject);

关闭

对于服务端的关闭,要完成以下工作:

(1)关闭所有连接的客户端。

for (int i = 0; i < ClientSockets.Count; i++)
{
    try
    {
        ClientSockets[i].Close();
    }
    catch (Exception ex)
    {
        //处理异常
    }
}
ClientSockets.Clear();

(2)如果服务端Socket是连接着的,需要先断开连接再关闭。由于每一步都会抛出异常,有必要保存每一步都会执行到。

try
{
    if (ServerSocket.Connected)
    {
        ServerSocket.Disconnect(false);
    }
}
catch (Exception ex)
{
    //
}
try
{
    ServerSocket.Close();
}
catch (Exception ex)
{
    //
}
finally
{
    ServerSocket = null;
}

回调函数中处理服务端关闭

采用异步接受客户端连接和接收客户端的数据,回调函数分别是AcceptCallback和ReceiveCallback。除了正常的接收外,在服务端关闭时,这两个函数也会被调用。这时候如果访问服务端,就会抛出异常。

所以在调用Socket前,可以先判断Socket是否已经关闭了。没有一个属性指明Socket关闭,可以调用一个属性抛出异常的方法判断。

try
{
    ServerSocket.Available;
}
catch
{
    //Socket关闭了
}

自动重连

由于服务端固定使用一个端口,反复重连会导致连接不上。所以在重连时,需要等待一段时间,让系统回收一些资源。实际上,除了用户主动关闭服务端,服务端关闭是很罕见的。那么,怎么监测服务端被动关闭呢?

我们在上面已经提到,服务端被关闭时,AcceptCallback和ReceiveCallback都会被调用,我们可以在AcceptCallback函数中完成对服务端的重启。重启时需要注意先把Socket关闭,等一段时间,再去开。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值