网络协议-3-TCP
2019-10-01 本文已影响0人
宠辱不惊的咸鱼
- TCP
- 传输控制协议 Transmission Control Protocol
- 概述
- 面向连接,可靠(差错校验),基于字节流,传输层协议
TCP头部结构
tcp-001.jpg- Sequence Number
- TCP报文段序号,解决网络包乱序,以及数据重传
- Acknowledgement Number
- 发送方期望的下一个TCP段的seq number
- Window
- 著名的滑动窗口(Sliding Window),用于流量控制
- 发送端
- LastByteAcked
- 已被接收端ACK的报文段
- LastByteSent
- 已发送出去的报文段,此时在网络传输中
- LastByteWritten
- 应用层正在写的位置
- LastByteAcked
- 接收端
- LastByteRead
- 应用层正在读的位置
- NextByteExpected
- 已接收连续报文段的位置
- LastByteRcvd
- 已接收最后一个报文段的位置
- 中间空白
- 还没到达的报文
- LastByteRead
- TCP Flag
- 8比特,即8个标识
- CWR,ECE,URG(urgent),ACK,PSH(push,发送数据),RST(reset),SYN,FIN
三次握手
tcp-002.jpg四次挥手
tcp-003.jpg客户端状态序列
tcp-004.jpg服务端状态序列
tcp-005.jpg状态转换
case CLOSED:
if(收到“被动打开”报文)
进入LISTEN状态
if(收到“主动打开”报文)
发送SYN报文段
进入SYN-SENT状态
if(收到任何报文段)
发送RST报文段
if(收到任何其他报文)
发出差错报文
break
case LISTEN:
if(收到“发送数据”报文)
发送SYN报文段
进入SYN-SENT状态
if(收到任何SYN报文段)
发送SYN+ACK报文
进入SYN-RCVD状态
if(收到任何其他报文段或者报文)
发出差错报文
break
case SYN-SENT状态:
if(超时)
进入CLOSED状态
if(收到SYN报文段)
发送SYN+ACK报文段
进入SYN-RCVD状态
if(收到SYN+ACK报文段)
发送ACK报文段
进入ESTABLISHED状态
if(收到其他任何报文段或者报文)
发出差错报文
break
case SYN-RCVD状态:
if(收到ACK报文段)
进入ESTABLISHED状态
if(超时)
发送RST报文段
进入CLOSED状态
if(收到“关闭”报文)
发送FIN报文段
进入FIN-WAIT-1状态
if(收到RST报文段)
进入LISTEN状态
if(收到任何其他报文段或者报文)
发出差错报文
break
case ESTABLISHED状态:
if(收到FIN报文段)
发送ACK报文段
进入CLOSE-WAIT状态
if(收到“关闭”报文)
发送FIN报文段
进入FIN-WAIT-1状态
if(收到RST或SYN报文段)
发出差错报文
if(收到数据或ACK报文段)
调用输入模块
if(收到“发送”报文)
调用输出模块
break
case FIN-WAIT-1状态:
if(收到FIN报文)
发送ACK报文段
进入CLOSING状态
if(收到FIN+ACK报文段)
发送ACK报文段
进入TIME-WAIT状态
if(收到ACK报文段)
进入FIN-WAIT-2状态
if(收到任何其他报文段或者报文)
发出差错报文
break
case FIN-WAIT-2状态:
if(收到FIN报文段)
发送ACK报文段
进入TIME-WAIT状态
break
case CLOSING状态:
if(收到ACK报文段)
进入TIME-WAIT状态
if(收到其他任何报文段或者报文)
发出差错报文
break
case TIME-WAIT状态:
if(超时)
进入CLOSED状态
if(收到FIN报文段)//自己补充的,我认为应该有这样一个
发送ACK报文段
if(收到其他任何报文段或者报文)
发出差错报文
break
case CLOSE-WAIT状态:
if(收到“关闭”报文)
发送FIN报文段
进入LAST-ACK状态
if(收到任何其他报文段或者报文)
发出差错报文
break
case LAST-ACK状态:
if(收到ACK报文段)
进入CLOSED状态
if(收到任何其他报文段或者报文)
发出差错报文
break
- 说明
- 客户端TIME_WAIT时,如果最后一次发送的ACK丢失了(怎么判定丢失呢,根据服务端补发的FIN来判定),它将重新发送ACK
- TIME_WAIT所等待时间依赖于具体实现方法
- 典型值为30秒,1分钟和2分钟
- 等待之后连接正式关闭,所有资源(包括端口号)被释放
- TIME_WAIT一般是2MSL(Maximum Segment Lifetime)