TCP数据传输
一、TCP简介
1、什么是TCP协议
TCP是面向连接的协议,这是因为在一个应用进程可以开始向另一个应用进程发送数据之前,这两个进程必须先相互“握手”,即它们必须相互发送某些预备报文段,以建立确保数据传输的参数。它有以下几个特点:
- 面向连接:TCP一定是“一对一”的,无法做到一对多;
- 可靠:无论的网络链路中出现了怎样的链路变化,TCP 都可以保证一个报文一定能够到达接收端(当然不是说绝对可靠);
- 基于字节流:消息是“没有边界”的,所以无论我们消息有多大都可以进行传输。并且消息是“有序的”,当前一个消息没有收到的时候,即使它先收到了后面的字节已经收到,那么也不能扔给应用层去处理,同时对重复的报文会自动丢弃。
2、为什么需要TCP协议
IP层是“不可靠”的,它不保证网络包的交付、不保证网络包的按序交付、也不保证网络包中数据的完整性。如果需要保障网络数据包的可靠性,那么就需要由上层(传输层)的 TCP 协议来负责。因为 TCP 是一个工作在传输层的可靠数据传输的服务,它能确保接收端接收的网络包是无损坏、无间隔、非冗余和按序的。
3、TCP头部格式
TCP头部的最小长度是 20字节。这是基本的TCP头部,不包含任何选项字段。TCP头部的最大长度是 60字节。当数据取最大32位时,TCP头部最大。
源端口号(16位) | 目标端口号(16位) | |||||||
---|---|---|---|---|---|---|---|---|
序列号(32位) | ||||||||
确认应答号(32位) | ||||||||
首部长度(4位) | 保留(6位) | URG | ACK | PSH | RST | SYN | FIN | 窗口大小(16位) |
校验和(16位) | 紧急指针(16位) | |||||||
选项(长度可变) | ||||||||
数据 |
- 源端口(Source Port):16位,发送方的端口号;
- 目标端口(Destination Port):16位,接收方的端口号;
- 序列号(Sequence Number):32位,发送数据段的序列号,用于数据重组;
- 确认号(Acknowledgment Number):32位,期望接收的数据段的下一个序列号,用于确认接收的数据;
- 数据偏移(Data Offset):4位,表示TCP头部的长度,以32位字(4字节)为单位;
- 保留位(Reserved):6位,保留为将来使用,通常置为0;
- 控制位(Control Flags):6位,包括以下标志:
- URG(紧急指针有效);
- ACK(确认号有效);
- PSH(推送数据);
- RST(重置连接);
- SYN(同步序列号,用于建立连接);
- FIN(终止连接)。
- 窗口大小(Window Size):16位,表示接收方允许发送方发送的数据量(以字节为单位);
- 校验和(Checksum):16位,用于检验数据的完整性;
- 紧急指针(Urgent Pointer):16位,指出紧急数据的结束位置,仅当URG标志置位时有效;
- 选项(Options):可变长度,包含额外的选项,如时间戳、窗口扩展等;
- 数据(Padding):可变长度,用于填充到32位边界。
二、Python传输TCP数据
用Python实现TCP数据传输需要从服务端(server)和客户端(client)两个部分来实现。
1、 服务端(server)
思路流程:
- 创建TCP套接字;
- 绑定套接字到指定的地址和端口;
- 使套接字开始监听连接请求;
- 接受新的连接;
- 接收来自客户端的数据;
- 发送确认消息回给客户端;
- 关闭和客户端的连接。
1 | import socket |
2、客户端(client)
思路流程:
- 创建TCP套接字;
- 连接到指定的服务器地址和端口;
- 编辑需要发送的数据;
- 发送数据给服务端;
- 接收来自服务端的响应数据;
- 关闭和服务端的连接。
1 | import socket |