TCP协议
概括
- 名称: 传输控制协议(Transmission Control Protocol)。
- 类别: 传输层协议。
- 特点: 面向连接的、可靠的、基于字节流的、可流量控制、拥塞避免。
详解
数据包组成
-
源端口、目的端头: 确定通信双方所用的进程。各占16 bit,范围0-65535。
-
序号: 传送的数据按字节编号,序号指该TCP包数据部分第一个字节的编号。占32 bit,表示0-232 byte。
-
确认号: 接收方给发送方的响应,指下个数据包从这个编号开始发。占32 bit。
-
数据偏移: 指TCP数据包多少个字节后就是数据部分了。4 bit,范围0-15,数据偏移的结果再 * 4才表示首部所占的字节数。即TCP首部(固定+可变+填充)最多15*4=60 byte。
-
保留: 无用的。6 bit。
-
URG: 表示本报文段中发送的数据是否包含紧急数据。URG=1,表示有紧急数据。后面的紧急指针字段只有当URG=1时才有效。
-
ACK: 表示是否前面的确认号字段是否有效。ACK=1,表示有效。只有当ACK=1时,前面的确认号字段才有效。TCP规定,连接建立后,ACK必须为1。
-
PSH: 告诉对方收到该报文段后是否应该立即把数据推送给上层。如果为1,则表示对方应当立即把数据提交给上层,而不是缓存起来。
-
RST: 只有当RST=1时才有用。如果你收到一个RST=1的报文,说明你与主机的连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接。或者说明你上次发送给主机的数据有问题,主机拒绝响应。
-
SYN: 在建立连接时使用,用来同步序号。当SYN=1,ACK=0时,表示这是一个请求建立连接的报文段;当SYN=1,ACK=1时,表示对方同意建立连接。SYN=1,说明这是一个请求建立连接或同意建立连接的报文。只有在前两次握手中SYN才置为1。
-
FIN: 标记数据是否发送完毕。当FIN=1,表明:数据发送完毕,可以释放连接。
-
窗口: 指告诉对方我接收数据的剩余缓冲区大小,让对方下一次发送的数据不要超出。
-
检验和: 验证数据的准确性,确保不接受传输过程中已改变的包。
-
紧急指针: 指数据包中需紧急处理的数据段,从1开始,到紧急指针所指的位置为紧急部分。
-
选项: 额外选项,如:最大报文段长度(MSS)、时间戳等等。
-
填充: 领填充,保证首部字节数是4的倍数。
TCP之可靠传输
原理:停止等待协议,自动重传请求
- 流量控制:通过调节滑动窗口的大小,使接收端能及时处理已在缓冲区的数据,不至于发送速率过快导致来不及处理引起包丢失。
- 拥塞控制:网络拥塞时,减少数据发送。慢开始,快恢复,快重传,拥塞避免算法。
TCP传输连接管理:3次握手,4次挥手。
-
建立连接,3次握手。简言之就是:请求建立连接,然后双向确认。
-
客户端向服务器请求建立连接。序号:x。
向服务器请求建立新的连接。
-
服务器确认收到请求并同意建立连接。序号:y,确认号:x+1。
收到建立连接的请求,并回复客户端同意建立该连接。服务器端给客户端的确认,表明客户端到服务器端的数据传输没有问题。
-
客户端收到同意的反馈后,告知服务器我已收到你的数据,连接正式建立。序号:x+1,确认号:y+1。
客户端收到服务器同意建立连接的反馈,告知服务器正式建立连接,可以传递数据。是客户端给服务器端的确认,确认服务器到客户端的数据传输没有问题。
客户端请求,服务器同意,两次握手也可以建立连接,为何一定要三次握手?
防止失效的连接请求被服务器接收,从而产生错误。
假设两次握手建立连接,客户端第一次请求建立连接的数据包由于网络拥塞迟迟到不了服务端,客户端会超时重发请求。当服务器接收了一个请求随后确认建立连接便开始传输数据。传输完成后客户端该进程关闭,此时另一个请求到达服务器,服务器确认建立连接,等待发送数据或主动发送数据。但此时的客户端已经关闭,服务器就会一直等待下去,这样耗费服务器的资源。
-
-
释放连接,4次挥手。
TCP是双向的,请两次挥手释放一个方向的连接,后两次挥手释放另一个方向的连接。
-
A数据发送完毕后,A向B请求释放连接,A–>B方向的。
A请求释放连接,此时A处于
FIN-WAIT-1
状态。 -
B收到A的请求,释放该方向连接,并告知A释放成功。
B同意释放该方向连接,B处于
CLOSE-WAIT
状态。反馈给A该方向连接已经释放,A处于FIN-WAIT-2
状态。
此时A–>B方向的连接已经断开,A不能向B发数据,B也不能接受A的数据。
-
B发送数据完毕后,B向A请求释放连接,B–>方向的。
B请求释放连接,此时B处于
LAST-ACK
状态。 -
A收到B的请求,释放该方向连接,并告知B释放成功。
A同意释放该方向连接,A处于
TIME-WAIT
状态。反馈给B该方向连接已经释放,B处于CLOSED
状态。而A需等待2MSL(Maximum Segment Lifetime)报文段最大寿命值,才进入CLOSED
状态。
为什么A要先进入TIME-WAIT状态,等待2MSL时间后才进入CLOSED状态?
为了保证B能收到A的确认应答。
若A发完确认应答后直接进入CLOSED状态,那么如果该应答丢失,B等待超时后就会重新发送连接释放请求,但此时A已经关闭了,不会作出任何响应,因此B永远无法正常关闭。
-