wiki/网络/TCPIP/TCP-IP.md
2025-01-02 10:46:09 +08:00

136 lines
9.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: TCP/IP
categories:
- TCP/IP
tags:
- TCP
date: 2022-08-22 21:45:25
---
# TCP/IP协议详解
## 一、什么是TCP/IP
TCP/IP是现代Internet的核心技术由IETF定义。互联网传输都需要依靠TCP/IP族其包含HTTP、Telnet、FTP、RIP、UDP等等
## 二、TCP/IP协议模型
![1](https://lzcwy-1257903760.cos.ap-beijing.myqcloud.com/%E7%BD%91%E7%BB%9C/TCPIP/1.png)
## 三、TCP/IP工作流程
![2](https://lzcwy-1257903760.cos.ap-beijing.myqcloud.com/%E7%BD%91%E7%BB%9C/TCPIP/2.jpg)
**源主机封包:**
1、 **应用层:**源主机将数据向下传输给传输层;
2、 **传输层:**将数据分组加上TCP首部形成TCP数据段向下传输给网络层
3、 **网络层:**给TCP数据段加上源主机、目的主机IP首部生成IP数据包向下传输给链路层
4、 **链路层:**链路层在其MAC帧的数据部分装上IP数据包再加上源主机目的主机的MAC地址和帧头并根据其目的的MAC地址将MAC帧发往目的主机或IP路由器
**目的主机拆包:**
1、 **链路层:**在目的主机链路层将MAC帧的帧头去掉并将IP数据包向上传递给网络层
2、 **网路层:**检查IP报头如果报头中校验和计算结果不一致则丢弃该IP数据包若校验和计算结果一致则去掉IP报头将TCP数据段向上传递给传输层
3、 **传输层:**检查顺序号判断是否是正确的TCP分组然后检查TCP报头数据若正确则向源主机发送确认信息若不正确或丢包则向源主机要求重发信息
4、 **应用层:**目的主机传输层去掉TCP报头将排好顺序的分组组成应用数据流送给应用程序这样目的主机接收到的来自源主机的字节流就像是直接接收来自源主机的字节流一样。
## 四、TCP报文格式
![3](https://lzcwy-1257903760.cos.ap-beijing.myqcloud.com/%E7%BD%91%E7%BB%9C/TCPIP/3.gif)
上图中 TCP 报文中每个字段的含义如下:
**源端口和目的端口字段**
TCP源端口Source Port源计算机上的应用程序的端口号占 16 位。
TCP目的端口Destination Port目标计算机的应用程序端口号占 16 位。
**序列号字段**
CP序列号Sequence Number占 32 位。它表示本报文段所发送数据的第一个字节的编号。在 TCP 连接中所传送的字节流的每一个字节都会按顺序编号。当SYN标记不为1时这是当前数据分段第一个字母的序列号如果SYN的值是1时这个字段的值就是初始序列值ISN用于对序列号进行同步。这时第一个字节的序列号比这个字段的值大1也就是ISN加1。
**确认号字段**
TCP 确认号Acknowledgment NumberACK Number占 32 位。它表示接收方期望收到发送方下一个报文段的第一个字节数据的编号。其值是接收计算机即将接收到的下一个序列号也就是下一个接收到的字节的序列号加1。
**数据偏移字段**
TCP 首部长度Header Length数据偏移是指数据段中的“数据”部分起始处距离 TCP 数据段起始处的字节偏移量,占 4 位。其实这里的“数据偏移”也是在确定 TCP 数据段头部分的长度,告诉接收端的应用程序,数据从何处开始。
**保留字段**
保留Reserved占 4 位。为 TCP 将来的发展预留空间,目前必须全部为 0。
**标志位字段**
- CWRCongestion Window Reduce拥塞窗口减少标志用来表明它接收到了设置 ECE 标志的 TCP 包。并且,发送方收到消息之后,通过减小发送窗口的大小来降低发送速率。
- ECEECN Echo用来在 TCP 三次握手时表明一个 TCP 端是具备 ECN 功能的。在数据传输过程中,它也用来表明接收到的 TCP 包的 IP 头部的 ECN 被设置为 11即网络线路拥堵。
- URGUrgent表示本报文段中发送的数据是否包含紧急数据。URG=1 时表示有紧急数据。当 URG=1 时,后面的紧急指针字段才有效。
ACK表示前面的确认号字段是否有效。ACK=1 时表示有效。只有当 ACK=1 时前面的确认号字段才有效。TCP 规定连接建立后ACK 必须为 1。
- PSHPush告诉对方收到该报文段后是否立即把数据推送给上层。如果值为 1表示应当立即把数据提交给上层而不是缓存起来。
- RST表示是否重置连接。如果 RST=1说明 TCP 连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接。
- SYN在建立连接时使用用来同步序号。当 SYN=1ACK=0 时,表示这是一个请求建立连接的报文段;当 SYN=1ACK=1 时表示对方同意建立连接。SYN=1 时,说明这是一个请求建立连接或同意建立连接的报文。只有在前两次握手中 SYN 才为 1。
- FIN标记数据是否发送完毕。如果 FIN=1表示数据已经发送完成可以释放连接。
**窗口大小字段**
窗口大小Window Size占 16 位。它表示从 Ack Number 开始还可以接收多少字节的数据量,也表示当前接收端的接收窗口还有多少剩余空间。该字段可以用于 TCP 的流量控制。
**TCP 校验和字段**
校验位TCP Checksum占 16 位。它用于确认传输的数据是否有损坏。发送端基于数据内容校验生成一个数值接收端根据接收的数据校验生成一个值。两个值必须相同才能证明数据是有效的。如果两个值不同则丢掉这个数据包。Checksum 是根据伪头 + TCP 头 + TCP 数据三部分进行计算的。
**紧急指针字段**
紧急指针Urgent Pointer仅当前面的 URG 控制位为 1 时才有意义。它指出本数据段中为紧急数据的字节数,占 16 位。当所有紧急数据处理完后TCP 就会告诉应用程序恢复到正常操作。即使当前窗口大小为 0也是可以发送紧急数据的因为紧急数据无须缓存。
**可选项字段**
选项Option长度不定但长度必须是 32bits 的整数倍。
## 五、TCP三次握手
![4](https://lzcwy-1257903760.cos.ap-beijing.myqcloud.com/%E7%BD%91%E7%BB%9C/TCPIP/4.png)
1. TCP服务器进程先创建传输控制块TCB时刻准备接受客户进程的连接请求此时服务器就进入了LISTEN监听状态
2. TCP客户进程也是先创建传输控制块TCB然后向服务器发出连接请求报文这是报文首部中的同部位SYN=1同时选择一个初始序列号 seq=x 此时TCP客户端进程进入了 SYN-SENT同步已发送状态状态。TCP规定SYN报文段SYN=1的报文段不能携带数据但需要消耗掉一个序号。
3. TCP服务器收到请求报文后如果同意连接则发出确认报文。确认报文中应该 ACK=1SYN=1确认号是ack=x+1同时也要为自己初始化一个序列号 seq=y此时TCP服务器进程进入了SYN-RCVD同步收到状态。这个报文也不能携带数据但是同样要消耗一个序号。
4. TCP客户进程收到确认后还要向服务器给出确认。确认报文的ACK=1ack=y+1自己的序列号seq=x+1此时TCP连接建立客户端进入ESTABLISHED已建立连接状态。TCP规定ACK报文段可以携带数据但是如果不携带数据则不消耗序号。
5. 当服务器收到客户端的确认后也进入ESTABLISHED状态此后双方就可以开始通信了。
## 六、TCP四次挥手
![5](https://lzcwy-1257903760.cos.ap-beijing.myqcloud.com/%E7%BD%91%E7%BB%9C/TCPIP/5.png)
1. 客户端进程发出连接释放报文并且停止发送数据。释放数据报文首部FIN=1其序列号为seq=u等于前面已经传送过来的数据的最后一个字节的序号加1此时客户端进入FIN-WAIT-1终止等待1状态。 TCP规定FIN报文段即使不携带数据也要消耗一个序号。
2. 服务器收到连接释放报文发出确认报文ACK=1ack=u+1并且带上自己的序列号seq=v此时服务端就进入了CLOSE-WAIT关闭等待状态。TCP服务器通知高层的应用进程客户端向服务器的方向就释放了这时候处于半关闭状态即客户端已经没有数据要发送了但是服务器若发送数据客户端依然要接受。这个状态还要持续一段时间也就是整个CLOSE-WAIT状态持续的时间。
3. 客户端收到服务器的确认请求后此时客户端就进入FIN-WAIT-2终止等待2状态等待服务器发送连接释放报文在这之前还需要接受服务器发送的最后的数据
4. 服务器将最后的数据发送完毕后就向客户端发送连接释放报文FIN=1ack=u+1由于在半关闭状态服务器很可能又发送了一些数据假定此时的序列号为seq=w此时服务器就进入了LAST-ACK最后确认状态等待客户端的确认。
5. 客户端收到服务器的连接释放报文后必须发出确认ACK=1ack=w+1而自己的序列号是seq=u+1此时客户端就进入了TIME-WAIT时间等待状态。注意此时TCP连接还没有释放必须经过2 *MSL最长报文段寿命的时间后当客户端撤销相应的TCB后才进入CLOSED状态。
6. 服务器只要收到了客户端发出的确认立即进入CLOSED状态。同样撤销TCB后就结束了这次的TCP连接。可以看到服务器结束TCP连接的时间要比客户端早一些。