2020年5月22日星期五

C# .NET Socket SocketHelper 高性能 5000客户端 异步接收数据

C# .NET Socket SocketHelper 高性能 5000客户端 异步接收数据


    网上有很多Socket框架,但是我想,C#既然有Socket类,难道不是给人用的吗?

    写了一个SocketServerHelper和SocketClientHelper,分别只有5、6百行代码,比不上大神写的,和业务代码耦合也比较重,但对新手非常友好,容易看懂。

    支持返回值或回调,支持不定长度的数据包。客户端和服务端均支持断线重连。

    自己本机测试,5000个客户端并发发送消息正常,CPU压力有点大。由于局域网机子性能差,局域网只测试了500个客户端并发发送消息正常。

    短短1000多行代码,花了好多天心血,改了无数BUG,越写代码,越觉得自己资质平平,逻辑思维不够用。写Socket代码不像写一般的代码,实在不行加个try catch完事,这个东西既要稳定,又要性能,真的是每一个逻辑分支,每一个异常分支,都要想清楚,都要处理好,代码里我还是Exception用习惯了,没细分。

    有时候为了解决一个BUG,找了一整天,也找不出BUG在哪,现在终于测试难过了,达到了自己的预想。

    通过这几天的踩坑,测试,得出结论:

    1、Socket TCP 不会丢包,TCP是可靠的。(本机测试、局域网测试,可能没有遇到更恶劣的网络环境)

    2、Socket TCP 能够保证顺序,接收到的顺序和发送的顺序一致

    3、代码里有数据校验,但是错误的分支永远都不会走,校验是一定能通过的,不存在数据校验不通过,把错误的数据包简单丢弃的情况,否则说明代码写的还是有BUG

    以下是主要代码:

    SocketServerHelper代码:

using Models;using Newtonsoft.Json;using System;using System.Collections.Concurrent;using System.Collections.Generic;using System.Configuration;using System.Linq;using System.Net;using System.Net.Sockets;using System.Runtime.InteropServices;using System.Text;using System.Threading;using System.Threading.Tasks;namespace Utils{ /// <summary> /// Socket服务端帮助类 /// </summary> public class SocketServerHelper {  #region 变量  private int _serverPort;  private Socket serverSocket;  private ConcurrentDictionary<ClientSocket, string> clientSocketList = new ConcurrentDictionary<ClientSocket, string>();  private ConcurrentDictionary<string, ClientSocket> _dictRoomNoClientSocket = new ConcurrentDictionary<string, ClientSocket>();  private ConcurrentDictionary<string, ClientSocket> _dictDevNoClientSocket = new ConcurrentDictionary<string, ClientSocket>();  public int _CallbackTimeout = 20;  /// <summary>  /// 等待回调超时时间(单位:秒)  /// </summary>  public int CallbackTimeout  {   get { return _CallbackTimeout; }   set { value = _CallbackTimeout; }  }  public int _WaitResultTimeout = 20;  /// <summary>  /// 等待返回结果超时时间(单位:秒)  /// </summary>  public int WaitResultTimeout  {   get { return _WaitResultTimeout; }   set { value = _WaitResultTimeout; }  }  private object _lockSend = new object();  public event EventHandler<ReceivedSocketResultEventArgs> ReceivedSocketResultEvent;  private System.Timers.Timer _checkClientTimer;  

没有评论:

发表评论