【C语言】TCP测速程序

2024-01-10 00:34:04

一、服务端

下面是一个用 C 语言编写的测试 TCP 传输速度的基本程序示例。
这只是一个简单示例,没有做详细的错误检查和边缘情况处理。在实际应用中,可能需要增加更多的功能和完善的异常处理机制。
TCP 服务器 (server.c):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define PORT 12345
#define BUFFER_SIZE 1024

int main() {
   int server_fd, new_socket;
   struct sockaddr_in address;
   int opt = 1;
   int addrlen = sizeof(address);
   char buffer[BUFFER_SIZE] = {0};

   // 创建 socket 文件描述符
   if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
       perror("socket failed");
       exit(EXIT_FAILURE);
   }

   // 设置 socket 选项
   if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
       perror("setsockopt");
       exit(EXIT_FAILURE);
   }

   address.sin_family = AF_INET;
   address.sin_addr.s_addr = INADDR_ANY;
   address.sin_port = htons(PORT);

   // 绑定 socket 到端口
   if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
       perror("bind failed");
       exit(EXIT_FAILURE);
   }

   // 监听端口
   if (listen(server_fd, 3) < 0) {
       perror("listen");
       exit(EXIT_FAILURE);
   }

   // 接受连接
   if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0) {
       perror("accept");
       exit(EXIT_FAILURE);
   }

   ssize_t bytes_read;
   printf("Server started, waiting for data...\n");

   // 清空 buffer
   memset(buffer, 0, BUFFER_SIZE);

   // 接收数据
   while ((bytes_read = recv(new_socket, buffer, BUFFER_SIZE, 0)) > 0) {
       // 可以在这里处理 buffer 数据,也可以添加其他逻辑,比如计算接收到的总字节数
       // 这里只做简单的演示,仅打印接收到的字节数
       printf("Bytes received: %zd\n", bytes_read);
   }

   if (bytes_read < 0) {
       perror("recv");
       exit(EXIT_FAILURE);
   }

   printf("Receiving data finished.\n");

   // 关闭连接
   close(new_socket);
   close(server_fd);

   return 0;
}

二、客户端

下面是用 C 语言编写的一个简单的 TCP 客户端程序,用来测试与 TCP 服务器之间的传输速度。这个程序会连接到指定服务器的指定端口,并发送固定大小的数据包一定次数,然后统计并显示传输速度。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>

#define SERVER_IP   "127.0.0.1" // 服务器 IP 地址
#define SERVER_PORT 12345        // 服务器端口号
#define DATA_SIZE   1024         // 发送数据包的大小 (bytes)
#define TOTAL_PACKS 10000        // 发送数据包的总数

int main() {
   int sock;
   struct sockaddr_in server_addr;
   char data[DATA_SIZE];
   ssize_t sent_bytes;
   clock_t start_time, end_time;
   double total_time, speed;

   // 创建 socket
   sock = socket(AF_INET, SOCK_STREAM, 0);
   if (sock < 0) {
       perror("socket");
       exit(EXIT_FAILURE);
   }

   // 指定服务器地址
   memset(&server_addr, 0, sizeof(server_addr));
   server_addr.sin_family = AF_INET;
   server_addr.sin_port = htons(SERVER_PORT);
   inet_aton(SERVER_IP, &server_addr.sin_addr);

   // 连接到服务器
   if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
       perror("connect");
       close(sock);
       exit(EXIT_FAILURE);
   }

   // 准备发送的数据
   memset(data, 'A', sizeof(data));

   // 开始计时
   start_time = clock();

   // 发送数据
   for (int i = 0; i < TOTAL_PACKS; i++) {
       sent_bytes = send(sock, data, sizeof(data), 0);
       if (sent_bytes < 0) {
           perror("send");
           close(sock);
           exit(EXIT_FAILURE);
       }
   }

   // 结束计时
   end_time = clock();

   // 关闭连接
   close(sock);

   // 计算总时间 (秒)
   total_time = (double)(end_time - start_time) / CLOCKS_PER_SEC;

   // 计算传输速度
   speed = (TOTAL_PACKS * DATA_SIZE) / (total_time * 1024 * 1024); // Mbps

   printf("Total time: %.3f seconds\n", total_time);
   printf("Data sent: %d MB\n", (TOTAL_PACKS * DATA_SIZE) / (1024 * 1024));
   printf("Transmission speed: %.3f Mbps\n", speed);

   return 0;
}

要注意的几点:
这个程序仅用于示例,未包含复杂的错误检查和异常情况处理。
SERVER_IP 和 SERVER_PORT 应当设置为要连接的服务器的 IP 地址和端口号。
DATA_SIZE 和 TOTAL_PACKS 可以根据需求调整数据包大小和发送次数以测试不同的传输速度。
程序计算的传输速度是理论值,实际传输速度会受到网络条件、服务器处理能力等多种因素的影响。
根据操作系统和编译环境,编译命令可能稍有不同。
编译和运行该程序前,确保服务器端程序正在运行并且监听指定端口。程序编译命令示例:

gcc -o tcp_client tcp_client.c

运行:

./tcp_client

如果需要更精确的时间测量,可以考虑使用更高精度的时间函数,如 gettimeofday() 或 C11 标准的 timespec_get()。

文章来源:https://blog.csdn.net/eidolon_foot/article/details/135491345
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。