创建TcpClient
定义
命名空间:TouchSocket.Sockets
程序集:TouchSocket.dll
一、说明
TcpClient
是Tcp系客户端基类,他直接参与tcp的连接、发送、接收、处理、断开等,他的业务与服务器的TcpSessionClient
是一一对应的。
二、特点
- 简单易用。
- IOCP多线程。
- 内存池支持
- 高性能
- 适配器预处理,一键式解决分包、粘包、对象解析(如HTTP,Json)等。
- 超简单的同步发送、异步发送、接收等操作。
- 基于委托、插件驱动,让每一步都能执行AOP。
三、产品应用场景
- 所有Tcp基础使用场景:可跨平台、跨语言使用。
- 自定义协议解析场景:可解析任意数据格式的TCP数据报文。
四、可配置项
可配置项
SetMaxPackageSize
数据包最大值(单位:byte),默认1024×1024×10。该值会在适当时间,直接作用DataHandlingAdapter.MaxPackageSize。
SetRemoteIPHost
链接到的远程IPHost,支持域名。支持类型:
- 使用IPv4,传入形如:127.0.0.1:7789的字符串即可。
- 使用IPv6,传入形如:[*::*]:7789的字符串即可。
- 使用域名,必须包含协议类型,形如:http://baidu.com或者https://baidu.com:80
- 使用IPv6域名,必须包含协议类型,形如:http://[*::*]:80
SetClientSslOption
客户端Ssl配置,为Null时则不启用。 注意,当RemoteIPHost使用https、wss的域名时,该配置会使用系统默认配置生效。
SetKeepAliveValue
为Socket设置的属性。 注意:该配置仅在window平台生效。
SetBindIPHost
绑定端口。
- 在UdpSessionBase中表示本地监听地址
- 在TcpClient中表示固定客户端端口号。
UseNoDelay
设置Socket的NoDelay属性,默认false。
UseReuseAddress
启用端口复用。该配置可在客户端在监听端口时,可以一定程度缓解端口来不及释放的问题。
SetMaxBufferSize
设置最大缓存容量,默认自动。
SetMinBufferSize
设置最小缓存容量,默认自动。
五、支持插件
插件方法 | 功能 |
---|---|
ITcpConnectingPlugin | 此时Socket实际上已经完成连接,但是并没有启动接收,然后触发。 |
ITcpConnectedPlugin | 同意连接,且成功启动接收后触发 |
ITcpClosingPlugin | 当客户端主动调用Close时触发 |
ITcpClosedPlugin | 当客户端断开连接后触发 |
ITcpReceivingPlugin | 在收到原始数据时触发,所有的数据均在ByteBlock里面。 |
ITcpReceivedPlugin | 在收到适配器数据时触发,根据适配器类型,数据可能在ByteBlock或者IRequestInfo里面。 |
ITcpSendingPlugin | 当即将发送数据时,调用该方法在适配器之后,接下来即会发送数据。 |
六、创建TcpClient
6.1 简单创建
简单的处理逻辑可通过Connected、Closed、Received等委托直接实现。
代码如下:
var tcpClient = new TcpClient();
tcpClient.Connecting = (client, e) => { return EasyTask.CompletedTask; };//即将连接到服务器,此时已经创建socket,但是还未建立tcp
tcpClient.Connected = (client, e) => { return EasyTask.CompletedTask; };//成功连接到服务器
tcpClient.Closing = (client, e) => { return EasyTask.CompletedTask; };//即将从服务器断开连接。此处仅主动断开才有效。
tcpClient.Closed = (client, e) => { return EasyTask.CompletedTask; };//从服务器断开连接,当连接不成功时不会触发。
tcpClient.Received = (client, e) =>
{
//从服务器收到信息。但是一般byteBlock和requestInfo会根据适配器呈现不同的值。
var mes = e.ByteBlock.Span.ToString(Encoding.UTF8);
tcpClient.Logger.Info($"客户端接收到信息:{mes}");
return EasyTask.CompletedTask;
};
//载入配置
await tcpClient.SetupAsync(new TouchSocketConfig()
.SetRemoteIPHost("127.0.0.1:7789")
.ConfigureContainer(a =>
{
a.AddConsoleLogger();//添加一个日志注入
}));
await tcpClient.ConnectAsync();//调用连接,当连接不成功时,会抛出异常。
Result result = await tcpClient.TryConnectAsync();//或者可以调用TryConnectAsync
if (result.IsSuccess())
{
}
tcpClient.Logger.Info("客户端成功连接");
6.2 继承实现
一般继承实现的话,可以从TcpClient
继承。如果有特殊需求,也可以从TcpClientBase
继承。
class MyTcpClient : TcpClient
{
protected override async Task OnTcpReceived(ReceivedDataEventArgs e)
{
//此处逻辑单线程处理。
//此处处理数据,功能相当于Received委托。
string mes =e.ByteBlock.Span.ToString(Encoding.UTF8);
Console.WriteLine($"已接收到信息:{mes}");
await base.OnTcpReceived(e);
}
}
var tcpClient = new MyTcpClient();
//载入配置
await tcpClient.SetupAsync(new TouchSocketConfig()
.SetRemoteIPHost("127.0.0.1:7789")
.ConfigureContainer(a =>
{
a.AddConsoleLogger();//添加一个日志注入
}));
await tcpClient.ConnectAsync();//调用连接,当连接不成功时,会抛出异常。
七、接收数据
在TcpClient