前言
Tcp是一个面向连接的流数据传输协议,用人话说就是传输是一个已经建立好连接的管道,数据都在管道里像流水一样流淌到对端。
那么数据必然存在几个问题,比如数据如何持续的读取,数据包的边界等。
Nagle's算法
Nagle 算法的核心思想是,在一个 TCP 连接上,最多只能有一个未被确认的小数据包(小于 MSS,即最大报文段大小)
优势
减少网络拥塞:通过合并小数据包,减少了网络中的数据包数量,降低了拥塞的可能性。
提高网络效率:在低速网络中,Nagle 算法可以显著提高传输效率。
劣势
增加延迟:在交互式应用中,Nagle 算法可能导致显著的延迟,因为它等待 ACK 或合并数据包。
C#中如何配置?
连接超时
在调用客户端Socket连接服务器的时候,可以设置连接超时机制,具体可以传入一个任务的取消令牌,并且设置超时时间。
SSL加密传输
TCP使用SSL加密传输,通过非对称加密的方式,利用证书,保证双方使用了安全的密钥加密了报文。在C#中如何配置?
服务端配置
客户端配置
KeepAlive
keepAlive不是TCP协议中的,而是各个操作系统本身实现的功能,主要是防止一些Socket突然断开后没有被感知到,导致一直浪费资源的情况。
其基本原理是在此机制开启时,当长连接无数据交互一定时间间隔时,连接的一方会向对方发送保活探测包,如连接仍正常,对方将对此确认回应
C#中如何调用操作系统的KeepAlive?
具体的开启,还需要看操作系统的版本以及不同操作系统的支持。
粘包断包处理
Pipe & ReadOnlySequence

上图来自微软官方博客:https://devblogs.microsoft.com/dotnet/system-io-pipelines-high-performance-io-in-net/
TCP面向应用是流式数据传输,所以接收端接到的数据是像流水一样从管道中传来,每次取到的数据取决于应用设置的缓冲区大小,以及套接字本身缓冲区待读取字节数。
C#中提供的Pipe就如上图一样,是一个管道Pipe有两个对象成员,一个是PipeWriter,一个是PipeReader,可以理解为一个是生产者,专门往管道里灌输数据流,即字节流,一个是消费者,专门从管道里获取字节流进行处理。
可以看到Pipe中的数据包是用链表关联的,但是这个数据包是从Socke缓冲区每次取到的数据包,它不一定是一个完整的数据包,所以这些数据包连接起来后形成了一个C#提供的另外一个抽象的对象ReadOnlySequence。
但是这里还是没有提供太好的处理断包和粘包的办法,因为断包粘包的处理需要两方面
1、业务数据包的定义
2、数据流切割出一个个完整的数据包
假设业务已经定义好了数据包,那么我们如何从Pipe中这些数据包根据业务定义来从不同的数据包中切割出一个完整的包,那么就需要ReadOnlySequence,它提供的操作方法,非常方便我们去切割数据,主要是头尾数据包的切割。
假设我们业务层定义了一个数据包结构,数据包是不定长的,包体长度每次都写在包头里,我们来实现一个数据包过滤器。
以上就是实现了固定数据包头实现粘包断包处理的部分代码。
关于TCP的连接还有一些,比如客户端连接限制,空闲连接关闭等。
如果大家对于完整代码感兴趣,可以看我刚写的一个TCP库
EasyTcp4Net
https://github.com/BruceQiu1996/EasyTcp4Net



1554

被折叠的 条评论
为什么被折叠?



