阅读《Linux高性能服务器编程》的笔记
TCP协议
一、特点
- 特点
- 面向连接。全双工
- 字节流
- 可靠传输
- 一对一,不适用于广播和多播(UDP更适合)
- 字节流
- 发送端。执行多次写操作,先放到TCP发送缓冲区。真正开始发送时,这些数据可能封装成一个或多个TCP报文段发出。和应用程序的写操作次数没关系。
- 接收端。收到一个或多个报文段,按序号以此放入接收缓冲区,通知应用程序读取数据。读取次数与应用成语都读缓冲区大小有关。
- 字节流:发送端写操作次数和接收端读次数没有数量关系。
- **UDP:**发送端应用程序每执行一次写操作,就会封装成一个UDP数据报发送。接收端必须及时对每一个UDP数据报执行读操作(recvfrom系统调用),否则会丢包。如果用户没有指定足够的应用程序缓冲区来读取UDP数据,则数据会被截断。
- 可靠传输
- 发送应答机制
- 超时重传。发送端发送数据时,启动定时器,到时未受到应答,重发报文段。
- TCP报文段是给IP数据报发送,IP数据报分片后在网络中传输可能乱序、重复,所以TCP协议接收到TCP报文段会先重排,整理,再交付给应用层。
二、三次握手与四次挥手
- 三次握手
- 客户端请求seq 111,SYN
- 服务器回应seq 222,ack 112,SYN
- 客户端回应ack 223
- 四次挥手
- 客户端(或服务器)seq 112,ack 223,FIN
- 服务器ack 113
- 服务器seq 223,ack 113,FIN
- 客户端ack 224
三、半关闭状态
- 概念
- 全双工,允许两个方向的数据传输被独立关闭。一方可以主动关闭连接,但能够继续接收数据。
- 流程
- 应用程序通过read系统调用返回0
四、连接超时
- 5次超时重传1,2,4,8,16,32
- 均失败就会通知应用程序
五、状态转移
六、TIME_WAIT状态
- 特点
- 在主动发起关闭的一方
- 需要等待2MSL(报文段最大生存时间)
- 原因
- **可靠地终止TCP连接。**如果报文段7没到服务器,服务器会重新发一个报文段6,此时刚好有2MSL,客户端处于TIME_WAIT处理重复收到的报文段6。
- **保证让迟来的TCP报文段有足够的时间被识别并丢弃。**当一个TCP连接是TIME_WAIT(一般在服务器),无法立即使用该连接占用的端口建立新连接。如果没有TIME_WAIT,建立的这个相似连接(ip,port都相同)就会接收原来连接的TCP报文段(迟到的报文段)。
七、复位报文段
- 访问不存在的端口
- 客户端访问不存在端口时,服务器返回一个复位报文段
- 复位报文段滑动窗口为0,因此客户端不回应,而是关闭连接或重新连接。
- 若服务器正处于TIME_WAIT,客户端也会收到复位报文段
- 异常终止连接
- 给对方发送一个复位报文段,发送端所有排队等待发送的数据都将被丢弃。
- 处于半打开连接
- 如果往半打开状态的连接写入数据,对方将回应一个复位报文段
八、TCP交互数据流
- 交互数据
- 包含很少的字节。对实时性要求高。ssh
- 成块数据
- 长度为TCP报文段允许的最大数据长度。对传输效率要求高。ftp
九、TCP超时重传
- 5次重传(0.2,0.4,0.8,1.6,3.2s)
- 5次都失败了,底层的IP和ARP开始接管
- 重传可以在超时之前,即快速重传
十、拥塞控制
-
过程
- 慢启动
- 拥塞避免
- 快速重传
- 快速恢复
-
几个概念
- SWND(发送窗口):限定了发送端能连续发送的TCP报文段数量。如果太小,会引起明显的网络延迟;如果太大,容易导致网络拥塞。
- SMSS(发送者最大段大小)
- RWND(接收通知窗口):控制SWND
- CWND(拥塞窗口)
- SWND = min(RWND, CWND)
-
慢启动和拥塞避免
(1)慢启动
- TCP刚建立连接,CWND设置为IW(2~4个SMSS)。此时最多发送IW个字节的数据。
- 发送端每收到接收端的一个确认,CWND+=min(N, SMSS)。N时此次确认中包含的之前未被确认的字节数。
- 以上过程就是慢启动算法。使用该算法的原因是,刚开始TCP并不知道网络的实际情况,试探性地平滑增加CWND的大小。
- 慢启动其实并不慢,指数形式扩大。
- 慢启动门限(ssthresh)。当CWND的大小超过该值,TCP进入拥塞避免阶段。
(2)拥塞避免
- CWND线性增加,减缓扩大。
- 快速重传和快速恢复
- 发送端连接收到3个重复的确认报文段,就认为拥塞发生。然后启用快速重传和快速恢复。
- 当收到第三个重复的确认报文段时,计算ssthresh = max(FlightSize/2, 2*SMSS)。FlightSize是已经发送但未收到确认的字节数。CWND=ssthresh+3*SMSS
- 每次收到1个重复确认时,设置CWND=CWND+SMSS。此时发送端可以发送新等待TCP报文段。
- 当收到新数据的确认时,设置CWND=ssthresh
- 快速重传和快速恢复完成后,拥塞控制恢复到拥塞避免阶段。