Home

Awesome

已发布Nuget:https://www.nuget.org/packages/EasyTcp4Net/ 或包管理器搜索EasyTcp4Net

这是一个基于c# Pipe,ReadonlySequence的高性能Tcp通信库,旨在提供稳定,高效,可靠的tcp通讯服务。

示例程序

一个示例的聊天程序,功能包括,文本发送,图片发送,断线重连,消息发送成功确认,消息发送失败提示等。 地址:https://github.com/BruceQiu1996/EasyChat

Pipe & ReadOnlySequence

alt text

为什么选择 Pipe & ReadOnlySequence

TCP 是一个流式面向连接的传输协议,所以源源不断地处理数据,并且在合适的地方进行数据分包,才是我们所关心的。Pipe本身是流水线一样的处理管道,我们只需要把我们收到的数据源源不断地扔到管道里,管道的消费端会帮我们进行数据处理

ReadOnlySequence 是多组数据的链表结构,更加符合了Tcp的流式传输的特征,并且它强大的多组数据切割能力,可以让我们非常方便的在多数据包中获取正确的数据。

Link:

https://learn.microsoft.com/zh-cn/dotnet/api/system.buffers.readonlysequence-1?view=net-7.0 https://learn.microsoft.com/zh-cn/dotnet/api/system.io.pipes?view=net-8.0

客户端配置(EasyTcpClientOptions)

KeyDescription
NoDelay是否不使用 Nagle's算法 避免了过多的小报文的过大TCP头所浪费的带宽
BufferSize流数据缓冲区大小
ConnectTimeout连接超时时间
ConnectRetryTimes连接失败尝试次数
ReadTimeout从socket缓冲区读取数据的超时时间
WriteTimeout向socket缓冲区写入数据的超时时间
IsSsl是否使用ssl连接
PfxCertFilenamessl证书
PfxPasswordssl证书密钥
AllowingUntrustedSSLCertificate是否允许不受信任的ssl证书
LoggerFactory日志工厂
KeepAlive是否启动操作系统的tcp keepalive机制
KeepAliveTimeKeepAlive的空闲时长,或者说每次正常发送心跳的周期,默认值为3600s(1小时)
KeepAliveProbesKeepAlive之后设置最大允许发送保活探测包的次数,到达此次数后直接放弃尝试,并关闭连接
KeepAliveIntvl没有接收到对方确认,继续发送KeepAlive的发送频率,默认值为60s
MaxPipeBufferSize待处理数据队列最大缓存,如果有粘包断包的过滤器,要大于单个包的大小,防止卡死

服务端配置(EasyTcpServerOptions)

KeyDescription
NoDelay是否不使用 Nagle's算法 避免了过多的小报文的过大TCP头所浪费的带宽
BufferSize流数据缓冲区大小
ConnectionsLimit最大连接数
BacklogCount连接等待/挂起连接数量
IsSsl是否使用ssl连接
PfxCertFilenamessl证书
PfxPasswordssl证书密钥
AllowingUntrustedSSLCertificate是否允许不受信任的ssl证书
MutuallyAuthenticate是否双向的ssl验证,标识了客户端是否需要提供证书
CheckCertificateRevocation是否检查整数的吊销列表
LoggerFactory日志工厂
IdleSessionsCheck是否开启空闲连接检查
CheckSessionsIdleMs空闲连接检查时间阈值
KeepAlive是否启动操作系统的tcp keepalive机制
KeepAliveTimeKeepAlive的空闲时长,或者说每次正常发送心跳的周期,默认值为3600s(1小时)
KeepAliveProbesKeepAlive之后设置最大允许发送保活探测包的次数,到达此次数后直接放弃尝试,并关闭连接
KeepAliveIntvl没有接收到对方确认,继续发送KeepAlive的发送频率,默认值为60s
MaxPipeBufferSize待处理数据队列最大缓存,如果有粘包断包的过滤器,要大于单个包的大小,防止卡死

开启一个Server

EasyTcpServer _server = new EasyTcpServer(_serverPort);
_server.StartListen();

开启一个Server并且配置SSL证书

EasyTcpServer easyTcpServer = new EasyTcpServer(7001, new EasyTcpServerOptions()
{
    IsSsl = true,
    PfxCertFilename = "xxx",
    PfxPassword = "xxx",
    IdleSessionsCheck = false,
    KeepAlive = true,
    CheckSessionsIdleMs = 10 * 1000
});

开启一个Server,配置数据过滤器处理粘包断包

固定头处理

//参数分别为:数据包头长度,数据包体长度所在头下标,数据包体长度字节数,是否小端在前
easyTcpServer.SetReceiveFilter(new FixedHeaderPackageFilter(7, 5, 4, true));

固定长度处理

//参数分别为:数据包固定长度
easyTcpServer.SetReceiveFilter(new FixedLengthPackageFilter(50));

固定字符处理(不推荐)

//参数分别为:截取的字符
easyTcpServer.SetReceiveFilter(new FixedCharPackageFilter('\n'));

客户端收到数据的回调

easyTcpClient.OnReceivedData += (obj, e) =>
{
    Console.WriteLine(string.Join(',', e.Data));
    Console.WriteLine("\n");
};

服务端收到数据的回调

easyTcpServer.OnReceivedData += async (obj, e) =>
{
    Console.WriteLine($"数据来自:{e.Session.RemoteEndPoint}");
    Console.WriteLine(string.Join(',', e.Data));
};

日志配置

var _server = new EasyTcpServer(_serverPort, new EasyTcpServerOptions()
{
    ConnectionsLimit = 2,
    LoggerFactory = LoggerFactory.Create(options => 
    {
        Log.Logger = new LoggerConfiguration()
        .MinimumLevel.Information()//最小的记录等级
        .MinimumLevel.Override("Microsoft", LogEventLevel.Information)//对其他日志进行重写,除此之外,目前框架只有微软自带的日志组件
        .WriteTo.Console()//输出到控制台
        .CreateLogger();

        options.AddSerilog();
    })
});