09 传输层协议(TCP/UDP)
TCP和UDP端口号-端口号
端口号用于区分一台服务器上不同的应用,访问同一台服务器的不同端口号会获取到不同的服务,例如:HTTP客户端访问HTTP服务器时,再封装传输层协议时,封装了源目端口号,再传输层通信需要建立套接字,CLIENT随机产生一个端口和服务器的服务端口建立连接,数据包在此连接通道中传输,服务端口号一般为1023以内的(也可以是其他的),客户端端口为大于1023的随机端口
TCP报文格式
Source Port:源端口,标识哪个应用传输的
Destination Port:目的端口,标识哪个应用程序接受
Sequence Number:序号字段。TCP链接中传输的每个字节上都甜上一个序号。Sequence Number字段的值指的是报文段所发送的数据的第一个字节的编号
Acknowledge Number:确认号,是期望收到的下一个报文段的数据第一个字节的序列号。即上次已经成功接受到的字节序列号加1。只有ACK标识为1,此字段有效
DATA Offset:数据偏移。即首部长度,指出TCP报文报文段的数据起始处距离TCP报文段的起始处有多远,正常为20字节
Reserved:保留字段。必须填0。
URG:紧急指针有效标识。他告诉系统此报文段中有紧急数据,应该尽快传递(相当于高优先级的数道)
ACK:确认序号有效标识。只有ACK=1时确认号才有效。当ACK=0时,确认号无效。
PSH:标识接收方应尽快将这个报文交给应用层
RST:重建连接标识。当RST=1表明TCP连接出现严重错误,必须释放连接,重建连接
SYN:同步序号标识。用来发起一个连接,SYN=1表示这是连接请求或接受请求
FIN:发端完成任务标识。用来释放一个连接,FIN=1标识此报文段的发送端的数据已经发送完毕,并要求释放连接
Window:TCP的流量控制,窗口起始于确认序号字段指明的值。这个值是接受端正期望接受的字节数。窗口最大为65535字节
Check num:校验字段,包括TCP首部和TCP数据,是一个强制性的字段,一定由发送端计算和存储,并由接收端进行验证。在计算校验和时,要在TCP报文段的前面加上12字节的伪首部
Urgent Pointer:紧急指针。只有当URG标识位位1才有用,紧急指针指出在本段报文段重紧急数据共有多少字节(紧急数据放在本报文段数据的最前面)
MSS和MTU差不多意思,指的是TCP包头和TCP数据的总长位多少字节限制
TCP的建立-三次握手
任何基于TCP的应用,在发送数据之前,都需要由TCP进行三次握手建立连接
由TCP连接发起方,发送第一个SYN位置1的TCP报文。初始序列号a为一个随机生成的数字,因为没收到过来自PC2的任何报文,所以确认序列号为0 ;
接收方(图中PC2)接收到合法的SYN报文之后,回复一个SYN和ACK置1的TCP报文。初始序列号b为一个随机生成的数字,同时因为此报文是回复给PC1的报文,所以确认序列号为a+1;
PC1接收到PC2发送的SYN和ACK置位的TCP报文后,回复一个ACK置位的报文,此时序列号为a+1,确认序列号为b+1。PC2收到之后,TCP双向连接建立。
TCP的序列号与确认序列号
TCP使用序列号和确认序列号字段实现数据的可靠和有序传输
PC1传输数据给PC2详细过程如下
- PC1将全部待TCP发送的数据按照字节为单位编上号。假设第一个字节的编号为“a+1”,第二个字节的序号为“a+2”,依次类推。
- PC1会把每一段数据的第一个字节的编号作为序列号(Sequence number),然后将TCP报文发送出去。
- PC2在收到PC1发送来的TCP报文后,需要给予确认同时请求下一段数据,如何确定下一段数据呢?序列号( a+1 )+载荷长度=下一段数据的第一个字节的序号(a+1+12)
- PC1在收到PC2发送的TCP报文之后,发现确认序列号为“a+1+12” ,说明“a+1”到“a+12”这一段的数据已经被接受,需要从“a+1+12”开始发送。
TCP滑动窗口机制
TCP通过滑动窗口机制来控制数据的传输速率。
完整控制过程
- 在TCP三次握手建立连接时,双方都会通过Window字段告诉对方本端最大能够接受的字节数(也就是缓冲区大小)。
- 连接建立成功之后,发送方会根据接受方宣告的Window大小发送相应字节数的数据。
- 接受方接受到数据之后会放在缓冲区内,等待上层应用来取走缓冲的数据。若数据被上层取走,则相应的缓冲空间将被释放。
- 接收方根据自身的缓存空间大小通告当前的可以接受的数据大小( Window )。
- 发送方根据接收方当前的Window大小发送相应数量的数据。
TCP的关闭 - 四次挥手
当数据传输完成,TCP需要通过“四次挥手”机制断开TCP连接,释放系统资源。
完整过程
- 由PC1发出一个FIN字段置”1 ”的不带数据的TCP段;
- PC2收到PC1发来的FIN置位的TCP报文后,会回复一个ACK置位的TCP报文。
- 若PC2也没有需要发送的数据,则直接发送FIN置位的TCP报文。假设此时PC2还有数据要发送,那么当PC2发送完这些数据之后会发送一个FIN置位的TCP报文去关闭连接。
- PC1收到FIN置位的TCP报文,回复ACK报文,TCP双向连接断开。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话