基础介绍
TCP/UDP是属于TCP/IP五层协议中的传输层协议。
TCP和UDP的区别:
TCP是点对点,可靠的(丢失重传,按序到达),面向连接的(传输数据需要先建立连接),传输效率较低。
UDP是支持一对一,一对多,多对多,不可靠的,无连接的(即发送数据之前不需要建立连接),传输效率较高。
TCP的报文结构:
(图片来源于网络,侵删)
Port:端口号,总共16位,所以范围是0~65535,其中小于256都是常用端口。
Sequence Number:记录当前TCP包的序列号,会与时间戳结合判断当前包的顺序。
为何需要结合时间戳:
- seq只有32位,当seq发送超过32位时,会归零后继续统计,如果序号2^32-1和序号0,需要判断这个包的顺序的话,就可以使用时间戳来识别哪个包的先后。
- 有时候TCP传输会因为网络原因传输比较慢,如果触发重发后,接收回应的时间较短,需要通过时间戳来判断也许是上一个序号包的回应。
Acknowledgment Number:回应已接收系列号为ack-1的数据,希望下一个序列号是ack
SYN:synchronous 建立连接
ACK:acknowledgment 确认
RST:reset 异常关闭
FIN:finish 终结连接
URG:urgent 紧急数据
PSH:Push立即把数据提交给上层,而不是缓存起来
CWR:接收ECE标志后,减少滑动窗口大小标志
ECE:网络线路拥堵
Window Size: 滑动窗口,用于流量控制(本节忽略)
Checksum: TCP数据包校验号,用于检测当前数据包是否异常
Urgent Pointer: 当URG为1时,指出当前数据包的紧急数据的字节数。
TCP三次握手
当A和B要进行TCP通信,传输数据前,必须要进行三次信息交换来建立连接,就是人人熟知的三次握手。握手最主要的目标就是让A,B双方知道自己的发送信息是正常,知道对方接受信息是正常的。
下面就是三次握手的有限状态机和建立需要传输的信息。
第一次握手,A向B发送SYN,同时消耗一个序列号, 这时B知道A的发送能力是正常的。
第二次握手,B向A发送SYN,回复ACK,同时也消耗一个序列号,这里说明发送SYN的时候会消耗序列号的,这时A知道自己的发送能力是正常的,B的接收能力也是正常的。
第三次握手,A向B回复ACK,这时A的接收能力是正常的,B知道自己的发送能力也是正常的。
所以三次握手都为了证明, A知道B的发送接收能力正常,自己的发送接收能力正常, B也知道A的发送接收能力正常,自己的发送接收能力正常。
A和B连接成功,开始交换数据。
Q: 如果TCP第三次握手失败,服务器会怎么样?
A:这种情况很有可能是遭受SYN Flood攻击,这时服务器会返回RST,然后关闭连接。
SYN Flood是攻击者伪装大量的IP地址去请求服务器进行TCP连接,服务器会把两次握手的连接放入半连接队列里,使得队列塞满,导致服务器无法响应。
TCP四次挥手
当A和B要断开连接的时候,就要进行四次挥手。挥手的主要目标就是要告诉对方,要断开连接了,请把数据都处理完,双方都确保可以关闭后就断开连接。
下面就是四次挥手的有限状态机和断开需要传输的信息。
第一次挥手,A向B发送FIN,进入半关闭状态,无法向B发送报文,只能发送回复。
第二次挥手,B向A回复ACK,B开始处理剩下的信息,然后准备关闭。
第三次挥手,B向A发送FIN,然后等待A的回应。
第四次挥手,A向B回复ACK,B进入关闭状态,A等待2MSL后,也进入了关闭状态。
其中2MSL表示的是报文最大生存时间,
一是为了确保B能正常收到最后的回复,
二是确保A没有收到B要求的重传(可能因为延迟,或者丢包导致要求重传),从而对下次复用连接造成影响。