【C语言】TCP测速程序

一、服务端

下面是一个用 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()。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/305921.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【c++】vector模拟

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;能手撕vector模拟 > 毒鸡汤&#xff1a;在等待…

动态规划(分割等和子集)

416. 分割等和子集 题目难易&#xff1a;中等 给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集&#xff0c;使得两个子集的元素和相等。 注意: 每个数组中的元素不会超过 100 数组的大小不会超过 200 示例 1: 输入: [1, 5, 11, 5] 输出: true 解释: 数…

STM32入门教程-2023版【3-3】gpio输入

关注 星标公众号 不错过精彩内容 大家好&#xff0c;我是硬核王同学&#xff0c;最近在做免费的嵌入式知识分享&#xff0c;帮助对嵌入式感兴趣的同学学习嵌入式、做项目、找工作! 上两小节我们已经把GPIO的结构和8种输入输出模式都讲完了&#xff0c;到这里还不懂的可以回…

浅析内存一致性:内存屏障

文章目录 概述内存乱序访问Store Buffer和Invalidate QueueStore BufferStore ForwardingStore Buffer与内存屏障 Invalidate QueueInvalidate Queue与内存屏障 内存屏障分类编译器屏障CPU内存屏障 相关参考 概述 内存屏障&#xff0c;是一类同步屏障指令&#xff0c;是CPU或编…

Java中的输入输出处理(一)

文件 文件&#xff1a;文件是放在一起的数据的集合。比如1.TXT。 存储地方&#xff1a;文件一般存储在硬盘&#xff0c;CD里比如D盘 如何访问文件属性&#xff1a;我们可以通过java.io.File类对其处理 File类 常用方法&#xff1a; 方法名称说明boolean exists()判断文件或目…

处理机调度与死锁

目录 进程调度算法先来先服务调度算法FCFS最短作业优先调度算法SJF最高优先级调度算法***HPF***高响应比优先调度算法 ***HRRN***时间片轮转调度算法***RR***多级队列调度算法MFQ 进程调度算法 进程调度算法也称为CPU调度算法 当 CPU 空闲时&#xff0c;操作系统就选择内存中…

一天一个设计模式---工厂方法

概念 工厂模式是一种创建型设计模式&#xff0c;其主要目标是提供一个统一的接口来创建对象&#xff0c;而不必指定其具体类。工厂模式将对象的实例化过程抽象出来&#xff0c;使得客户端代码不需要知道实际创建的具体类&#xff0c;只需通过工厂接口或方法来获取所需的对象。…

uniapp中uview组件库丰富的Table 表格的使用方法

目录 #平台差异说明 #基本使用 #兼容性 #API #Table Props #Td Props #Th Props 表格组件一般用于展示大量结构化数据的场景 #平台差异说明 AppH5微信小程序支付宝小程序百度小程序头条小程序QQ小程序√√√√√√√ #基本使用 本组件标签类似HTML的table表格&#…

模型评估:评估指标的局限性

“没有测量&#xff0c;就没有科学。”这是科学家门捷列夫的名言。在计算机科学特别是机器学习领域中&#xff0c;对模型的评估同样至关重要。只有选择与问题相匹配的评估方法&#xff0c;才能快速地发现模型选择或训练过程中出现的问题&#xff0c;迭代地对模型进行优化。模型…

猫头虎分享:Linux 如何安装最新版的Docker和Docker-Compose 教程 ‍

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通Golang》…

教你如何将本地虚拟机变成服务器,供其它电脑访问

场景&#xff1a;最近在做数据仓库的作业&#xff0c;需要团队协作&#xff0c;买不起阿里云服务器&#xff0c;所以想到能不能将我本地机上的虚拟机变成服务器&#xff0c;供其它同学的电脑访问。在虚拟机上安装hadoop和hive&#xff0c;然后同学机子上安装kettle进行连接。最…

书生大模型全链路开源体系

书生浦语大模型全链路开源体系开源了哪些东西 数据书生万卷&#xff1a;一个2TB的涵盖多种模态与任务的数据集预训练InternLM-Train&#xff1a;微调XTuner&#xff1a;可供你低成本微调模型的工具箱部署LMDeploy&#xff1a;一个服务端场景下、transformer 结构 LLM 部署工具…

【模拟IC学习笔记】Cascode OTA 设计

辅助定理 增益Gm*输出阻抗 输出短路求Gm 输入置0求输出阻抗 求源极负反馈的增益 随着Vin的增加&#xff0c;Id也在增加&#xff0c;Rs上压降增加&#xff0c;所以&#xff0c;Vin的一部分电压体现在Rs上&#xff0c;而不是全部作为Vgs&#xff0c;因此导致Id变得平滑。 Rs足…

Python书籍推荐,建议收藏

学习Python的书籍可太多了&#xff0c;从入门到放弃&#xff0c;应有尽有啊 入门书籍 根据豆瓣评分的高低&#xff0c;这里介绍了一些经典入门书籍&#xff0c;大家根据自身情况选择尝试 《Python编程&#xff1a;从入门到实践&#xff08;第二版&#xff09;》 非常经典且非…

搜维尔科技:第九届元宇宙数字人设计大赛作品规范解读!

作品提交 参赛小组需要将作品上传至百度网盘&#xff0c;并将分享链接发送至frankaxis3d.cn邮箱。邮寄格式如下&#xff1a; 邮件标题&#xff1a;作品名称元宇宙数字人设计大赛作品 邮件内容标明&#xff1a;学校名称、院系名称、作品名称、作者名称、联系电话及指导老师名…

vue中鼠标拖动触发滚动条的移动

前言 在做后端管理系统中&#xff0c;像弹窗或大的表单时&#xff0c;经常会有滚动条的出现&#xff0c;但有些时候如流程、图片等操作时&#xff0c;仅仅使用鼠标拖动滚动条操作不太方便&#xff0c;如果使用鼠标拖拽图片或容器来触发滚动条的移动就比较方便了 功能设计 如…

【leetcode】力扣算法之删除链表中倒数第n个节点【中等难度】

删除链表中倒数第n个节点 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 用例 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5] 输入&#xff1a;head [1], n 1 输出&#xff1a;[] 输入&#xff1a;head …

蓝牙模块在电动汽车充电设施中的创新应用

随着电动汽车的普及&#xff0c;充电设施的便捷性和智能化成为关键的发展方向。蓝牙技术作为一种无线通信技术&#xff0c;在电动汽车充电设施中发挥着越来越重要的作用。本文将深入探讨蓝牙模块在电动汽车充电设施中的创新应用&#xff0c;以提高充电体验、提升管理效率&#…

“程序员面试之道:成为求职战场上的不可忽视的力量“

文章目录 每日一句正能量前言面试经历面试技巧后记 每日一句正能量 看淡拥有&#xff0c;不刻意追求某些东西&#xff0c;落叶归根&#xff0c;那些属于你的&#xff0c;总会回来。 前言 在现代科技发展日新月异的时代&#xff0c;程序员无疑扮演着重要的角色。他们是代码的创…

我的1827创作纪念日

机缘 习惯性早上打开电脑&#xff0c;看看CSDN上的资讯&#xff0c;了解行业动态、当前新的技术和大佬的分享。自己动手写应该是2019 年 01 月 08 日&#xff0c;当时应该是在用安装和使用Oracle&#xff0c;遇到一些问题&#xff0c;写下第一篇博客 Oracle存储过程常见问题及…