Bootstrap

【Linux】超时重传机制

超时重传机制

超时重传机制是一种常见的网络协议设计策略,用于确保数据包在不可靠网络中的可靠传输。它特别适用于UDP等不提供内建可靠性保障的协议。以下是超时重传机制的基本概念和实现方法。

1. 基本概念

在数据传输过程中,发送方在发送数据包后启动一个定时器。如果在预设的超时时间内没有收到接收方的确认(ACK),发送方会重新发送该数据包。

2. 工作流程
  • 数据发送:发送方发送数据包,并启动定时器。
  • 等待确认:发送方在等待ACK的同时监控定时器。
  • 超时处理
    • 如果在超时之前收到ACK,定时器停止,继续发送下一个数据包。
    • 如果超时未收到ACK,发送方重新发送该数据包,并重启定时器。
3. 超时计算

超时值的选择至关重要,通常需要考虑以下因素:

  • 网络延迟:根据网络的平均往返时间(RTT)来设置超时。
  • 动态调整:通过历史数据动态调整超时值,以适应网络状态变化。
4. 应用示例
#include <iostream>
#include <chrono>
#include <thread>
#include <cstdlib> // 用于rand和srand
#include <ctime>   // 用于time

// 模拟发送数据
bool sendData(const std::string& data) {
    // 这里可以放置实际的发送逻辑
    std::cout << "Sending data: " << data << std::endl;
    return rand() % 2; // 模拟50%的概率成功
}

// 模拟接收确认
bool receiveAck() {
    return rand() % 2; // 模拟50%的概率收到ACK
}

// 计算超时值(示例)
int calculateTimeout() {
    return 1000; // 返回超时值为1000毫秒
}

void sendWithRetransmission(const std::string& data) {
    int timeout = calculateTimeout(); // 计算初始超时值
    int maxRetries = 5; // 最大重传次数

    for (int attempts = 0; attempts < maxRetries; ++attempts) {
        if (sendData(data)) {
            // 成功发送,等待ACK
            std::cout << "Waiting for ACK..." << std::endl;
            std::this_thread::sleep_for(std::chrono::milliseconds(timeout)); // 模拟超时
            if (receiveAck()) {
                std::cout << "ACK received!" << std::endl;
                break; // 收到确认,退出循环
            } else {
                std::cout << "Timeout, resending data..." << std::endl;
            }
        } else {
            std::cout << "Failed to send data, retrying..." << std::endl;
        }
    }
    std::cout << "Max retries reached. Giving up." << std::endl;
}

int main() {
    srand(static_cast<unsigned>(time(0))); // 用当前时间种子初始化随机数生成器
    sendWithRetransmission("Hello, World!"); // 调用发送函数
    return 0;
}

代码说明

  • sendData函数模拟数据发送,并随机决定是否成功发送。
  • receiveAck函数模拟接收ACK的过程。
  • calculateTimeout函数简单返回固定的超时值,你可以根据需要实现更复杂的超时计算逻辑。
  • sendWithRetransmission函数中,发送数据后等待ACK,如果超时未收到ACK则进行重传,最多重试指定次数。
;