You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在RTT计算代码中添加循环,实现10次试验并计算平均RTT?

实现多次RTT测试并计算平均值

问题描述

需要计算客户端与服务器之间n次试验的平均RTT(往返时间),现有一段可计算单次RTT的C语言代码,但不清楚应将代码的哪一部分包裹在循环中,以完成10次RTT测试并计算平均值。当前代码完成一次计算后难以重复测试,可通过终端输入URL和端口号(例如./client www.example.com 80)运行测试。

修改后的完整代码

#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/time.h>

#define RCVBUFSIZE 32
#define TEST_COUNT 10  // 测试次数

void DieWithError(char *errorMessage);
int getAddressInfo(const char* host, unsigned short* port, struct sockaddr_in* sock_addr);

int main(int argc, char *argv[]) {
    struct sockaddr_in httpServAddr;
    unsigned short httpServPort;
    char *httpRequest = "GET / HTTP/1.1\r\n"  // 修正GET后的空格,否则请求无效
                        "Host: %s\r\n"
                        "Connection: close\r\n\r\n";
    const char* host;

    if (argc < 2 || argc > 3) {
        fprintf(stderr, "Usage: %s <Server IP/URL> [<HTTP Port>]\n", argv[0]);
        exit(1);
    }

    host = argv[1];

    memset(&httpServAddr, 0, sizeof(httpServAddr));
    if (getAddressInfo(host, &httpServPort, &httpServAddr) != 0) {
        DieWithError("Failed to get server address information");
    }

    if (argc == 3) {
        httpServPort = atoi(argv[2]);
    } else {
        httpServPort = 80;
    }
    httpServAddr.sin_port = htons(httpServPort);

    long total_rtt = 0;
    for (int i = 0; i < TEST_COUNT; i++) {
        int sock;
        char httpBuffer[RCVBUFSIZE];
        int bytesRcvd, totalBytesRcvd;
        char request[strlen(httpRequest) + strlen(host) + 1];

        // 每次测试重新创建socket并连接
        if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
            DieWithError("socket() failed");
        }

        if (connect(sock, (struct sockaddr *) &httpServAddr, sizeof(httpServAddr)) < 0) {
            DieWithError("connect() failed");
        }

        sprintf(request, httpRequest, host);
        if (send(sock, request, strlen(request), 0) != strlen(request)) {
            DieWithError("send() sent a different number of bytes than expected");
        }

        totalBytesRcvd = 0;
        printf("=== Test %d Received: ===\n", i+1);

        struct timeval start, end;
        gettimeofday(&start, NULL);

        while ((bytesRcvd = recv(sock, httpBuffer, RCVBUFSIZE - 1, 0)) > 0) {
            totalBytesRcvd += bytesRcvd;
            httpBuffer[bytesRcvd] = '\0';
            printf("%s", httpBuffer);
        }

        gettimeofday(&end, NULL);
        long rtt = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000;
        total_rtt += rtt;

        if (bytesRcvd < 0) {
            DieWithError("recv() failed");
        }

        printf("\nRound-trip time for test %d: %ld ms\n\n", i+1, rtt);
        close(sock);  // 每次测试结束关闭socket
    }

    printf("=== Average RTT over %d tests: %ld ms ===\n", TEST_COUNT, total_rtt / TEST_COUNT);
    exit(0);
}

int getAddressInfo(const char* host, unsigned short* port, struct sockaddr_in* httpServAddr) {
    struct addrinfo hints = {0};
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;

    struct addrinfo* result;
    int ret = getaddrinfo(host, NULL, &hints, &result);
    if (ret != 0) {
        fprintf(stderr, "getaddrinfo() failed: %s\n", gai_strerror(ret));
        return -1;
    }
    memcpy(httpServAddr, (struct sockaddr_in*)result->ai_addr, sizeof(struct sockaddr_in));
    *port = ntohs(httpServAddr->sin_port);

    freeaddrinfo(result);
    return 0;
}

void DieWithError(char *errorMessage) {
    perror(errorMessage);
    exit(1);
}

关键修改说明

  • 定义TEST_COUNT常量指定测试次数(这里设为10),用循环包裹完整的socket创建、连接、请求发送、数据接收、RTT计算流程,因为每次测试需要重新建立TCP连接(请求中指定了Connection: close,服务器会在响应后关闭连接)。
  • 将total_rtt变量移到循环外,用于累加每次测试的RTT值,最后计算平均值。
  • 修正了原代码中GET/的错误,改为GET /,否则HTTP请求格式无效,会导致服务器返回错误。
  • 每次循环结束后调用close(sock)关闭当前socket,避免资源泄漏。
  • 增加了测试序号的输出,方便区分每次测试的结果。

内容的提问来源于stack exchange,提问作者PikaKirbyBro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 08:48:16