TCP协议通过以下机制来保证数据的可靠传输:
- 建立连接:在发送数据前,客户端和服务器首先建立连接,之后所有数据都在连接内传输。
- 序号和确认:每个报文都带有序号,接收方返回确认报文ACK,确认收到的数据序号,发送方根据ACK重传丢失数据。
- 超时重传:如果一段时间内没有收到ACK,发送方会重传数据,以修复可能丢失的报文。
- 滑动窗口:通过窗口大小控制发送方能发送的最大未确认数据量,避免接收方资源耗尽。
- 断开连接:数据传输完成后,通过四次握手断开连接,释放资源。
- 拥塞控制:根据网络拥塞情况调整窗口大小,控制发送速率,避免网络拥塞。
- 重复ACK:当接收方收到失序的数据时,会多次发送同一确认报文,发送方收到3个重复ACK时就立即重传,加快修复速度。
代码示例:
python
from random import Random
# 初始化参数
seq = 0 # 序号
ack_seq = 0 # 确认序号
window_size = 5 # 滑动窗口大小
timeout = 0.5 # 超时时间
dup_ack = 0 # 重复ACK数量
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 建立连接
# 发送方超时重传
def retransmit(seq):
print('超时重传:', seq)
sock.send(data[seq])
# 收到确认报文
def ack(ack_seq):
global seq, dup_ack
seq = ack_seq # 更新序号
dup_ack = 0 # 重复ACK数清零
# 滑动窗口内继续发送数据
while seq - ack_seq < window_size:
sock.send(data[seq])
seq += 1
# 收到重复确认
def dup_ack():
global dup_ack
dup_ack += 1
if dup_ack == 3: # 收到3个重复ACK,重传
retransmit(ack_seq)
dup_ack = 0
# 生成随机数据
data = [Random().randbytes(1024) for _ in range(20)]
# 启动定时器,每隔timeout时间检查一次
timer = threading.Timer(timeout, retransmit(seq))
timer.start()
# 接收ACK和重复ACK,并作出响应
while True:
msg = sock.recv(1024)
if msg.startswith('ACK'):
ack(int(msg.split()[1]))
elif msg.startswith('DUP_ACK'):
dup_ack()
TCP通过上述机制来保证可靠数据传输。理解TCP如何实现可靠传输,有助于我们设计、优化网络应用,并进行网络故障排查。掌握TCP可靠传输机制是网络编程的基础。