运输层协议——TCP

1.TCP和UDP是传输层两个重要的协议。
TCP提供面向连接、可靠的字节流服务。使用TCP协议的两端必须先建立连接,才能开始数据的读写,双方必须都为连接分配必要的数据结构。TCP有发送缓冲区和接收缓冲区,TCP模块发出的数据报的个数和应用程序执行的写操作次数之间没有固定的关系。TCP的连接是全双工的。

UDP提供面向无连接,不可靠的数据报服务。发送端每执行一次写操作,UDP模块就将其封装成UDP数据报并发送,接收端必须及时接收,否则就会丢包。

2.TCP的可靠传输体现的几个方面
(1)发送应答机制。发送端发送的每个TCP报文段都必须接到接收方的应答。

(2)超时重传机制。发送端在发送一个TCP报文后,立即启动一个定时器,如果在定时器时间内没有收到应答报文,则重传该TCP报文。

(3)对TCP报文进行重排、整理。因为TCP报文最终是被以IP数据报传输的,IP数据报是乱序、重复的,TCP会对IP数据报进行排序整理,再交给应用层。

3.TCP报文的报头
运输层协议——TCP

(1)16位端口号:进行TCP通信时,客户端的端口号通常是系统自己选择的临时端口号,服务器使用知名端口号。

(2)32位序号:一次TCP通信过程中,某个传输方向上的字节流的每个字节的编号。在第一次通信时,***被系统初始化为某个随机值ISN,后续的序列后为ISN+数据第一个字节在整个字节流中的偏移。

(3)32确认号:用作对另一个方发送来的TCP报文段的相应。其值是收到的报文段的***+1。

(4)4位头部长度:用来标识该TCP头部有多少个32字节,因为只有4位,所以,TCP的头部最大为60字节。

(5)6位标识位:
URG位:表示紧急指针是否有效
ACK位:表示确认号是否有效。带有ACK标识的报文段为确认报文段
PSH位:提示接收端应用程序应该立即从缓冲区读取数据,以便为接收数据流出地方
RST位:表示要求对方重新建立连接。带有RST标识的报文段为复位报文段
SYN位:表示请求建立一个连接。带有SYN标识的报文段为同步报文段
FIN位:表示通知对方本端要关闭连接了。带有FIN标识的报文段为结束报文段

(6)16位窗口大小:是TCP流量控制的一个手段。他告诉对方本端的TCP接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据。

(7)16位校验和:由发送端填充,接收端对TCP报文段执行CRC算法以检验TCP报文段在传输过程中是否损坏。TCP数据报(报头+数据部分)校验

(8)16位紧急指针:一个正的偏移量。这个字段是紧急指针相对于当前序号的偏移。

4.TCP连接的建立和关闭

(1)正常连接和关闭
运输层协议——TCP

(2)半连接状态
运输层协议——TCP
收到SYN报文,但是没有收到ACK报文时候的状态为半连接状态。

在三次握手过程中,服务器维护了一个半连接队列,该队列为每一个收到SYN并向客户端发出确认,但是没有收到ACK,正在等待客户端的确认的连接开设一个条目。这些条目里的连接都处于SYN_RCVD状态。当服务收到客户端的ACK确认后,删除该条目,服务器处于ESTABLISHED状态。

(3)半关闭状态
运输层协议——TCP

由于TCP连接是全双工的,它允许两个方向的数据传输被独立的关闭。通信的乙方可以发送结束报文给对方,告诉它本端已经完成了数据的传送,但是可以接收对方的数据,直到对方也发送结束报文关闭连接,这种状态称为半关闭。

(4)半打开状态

服务器或客户端关闭或者异常终止了连接,而对方没有接收到结束报文段,此时,客户端还维持着原来的状态,而服务器即使重启,也已经没有该连接的任何消息了,这种状态称为半打开状态,该连接称为半打开连接。如果客户端或服务器端往半打开连接写入数据,则对方将回应一个复位报文。

(5)TCP状态转移图
运输层协议——TCP
客户端connect主动发起连接,服务器端通过listen系统调用处于listen状态,被动等待客户端的连接。

client向server发送SYN报文,自己处于SYN_SENT状态;
server收到SYN报文,发送ACK和自己的SYN报文给server,处于SYN_RCVD状态;
clients收到server的ACK和SYN报文,发送ACK报文给client,处于ESTABLISHED状态;
server收到client的ACK报文,处于ESTABLISHEND状态;
当服务器和客户端成功建立连接后,二者处于ESTABLISHED状态,ESTABLISHED状态是连接双方可以进行双向通信的状态

假设:client首先关闭连接
client发送FIN报文给server,自己处于FIN_WAIT_1状态;
server收到FIN报文,发送ACK报文给client,自己处于CLOAE_WAIT状态;
client收到ACK报文,处于FIN_WAIT_2状态;
……………………………………server的数据发送完毕…………………………………….
server发送FIN报文给client,自己处于LAST_ACK状态;
client收到FIN报文,发送ACK给server,自己处于TIME_WAIT状态;
server收到ACK报文,处于CLOSED状态;
经过2MSL后,client处于CLOSED状态。

5.connect系统调用失败的原因
<1>connect的目标端口不存在,或者该端口被处于TIME_WAIT状态的连接所占用的时候,服务器给客户端发送一个RST复位报文,connect调用失败;
<2>目标端口存在,但是connect在超时时间内未收到服务器的确认报文段,则connect失败。

6.TIME_WAIT状态存在的原因
<1>可靠的终止TCP连接。如果最后发送的ACK报文丢失,TIME_WAIT状态可以对FIN报文做回应,从而可靠的结束TCP连接。
<2>保证让迟来的TCP报文段有时间被释放。
TIME_WAIT状态一般为2MSL,让属于这一连接的所有数据都完全被清理干净。

7.产生复位报文段的情况:
<1>访问不存在的端口;
<2>异常终止连接;
<3>处理半打开连接。如果客户端/服务器端向半打开连接写入数据,对方则回应一个复位报文。

8.带外数据
带外数据比普通数据具有更高的优先级,TCP利用其头部中的紧急指针标识和紧急指针两个字段,给应用程序提供了一种紧急方式。
TCP接收端只有在接收到紧急指针标识时,才会检查紧急指针,然后根据紧急指针所指的位置确定带外数据的位置,并将它读入一个特殊的缓冲中。这个带外缓存只有1字节,如果上层应用没有及时将带外数据读出,则后面的带外数据将覆盖它。

9.TCP超时重传
TCP模块为每个TCP报文段都维护了一个重传定时器,该定时器在TCP数据报第一次被发送的时候被启动。如果在超时时间内未收到接收方的应答,TCP模块将重新传TCP报文并重置定时器。

TCP重传策略:
Linux的内核参数/proc/sys/net/ipv4/tcp_retries1指定在底层IP管道之前最少执行的重传次数
Linux的内核参数/proc/sys/net/ipv4/tcp_retries2指定连接放弃前,TCP最多可以执行的重传次数