TCP 如何保证数据的可靠传输?

TCP协议通过以下机制来保证数据的可靠传输:

  1. 建立连接:在发送数据前,客户端和服务器首先建立连接,之后所有数据都在连接内传输。
  2. 序号和确认:每个报文都带有序号,接收方返回确认报文ACK,确认收到的数据序号,发送方根据ACK重传丢失数据。
  3. 超时重传:如果一段时间内没有收到ACK,发送方会重传数据,以修复可能丢失的报文。
  4. 滑动窗口:通过窗口大小控制发送方能发送的最大未确认数据量,避免接收方资源耗尽。
  5. 断开连接:数据传输完成后,通过四次握手断开连接,释放资源。
  6. 拥塞控制:根据网络拥塞情况调整窗口大小,控制发送速率,避免网络拥塞。
  7. 重复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可靠传输机制是网络编程的基础。