Linux系统TCP连接性能

一、测试环境

  1. debian11 64bit

  2. 设置系统网络限制

    sudo vi /etc/sysctl.conffs.file-max=10485760net.ipv4.ip_local_port_range=1024 65535#net.ipv4.tcp_tw_recycle=1net.ipv4.tcp_tw_reuse=1net.ipv4.tcp_timestamps=1net.core.rmem_default=209715200net.core.wmem_default=209715200net.core.rmem_max=209715200net.core.wmem_max=209715200
    sudo /sbin/sysctl -p
    
  3. 设置文件描述符

    sudo vi /etc/security/limits.conf root soft nofile 65535root hard nofile 65535
    sudo vi /etc/profileulimit -SHn 65535sudo reboot
    

二、测试代码

  1. 服务端代码: tcpserver.c

    #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>
    #include <sys/time.h>
    #include <pthread.h>#define CONNECT_NUM 65535static int fd_count = 0;
    static int fd_list[CONNECT_NUM] = {0};
    pthread_mutex_t	connect_mutex;void* connect_thread(void* arg){uint16_t port = (uint16_t)arg;int sockfd = socket(AF_INET,SOCK_STREAM,0);if(sockfd < 0){printf("socket error!\n");exit(-1);}struct sockaddr_in my_addr;memset(&my_addr, 0, sizeof(my_addr));my_addr.sin_family=AF_INET;my_addr.sin_port=htons(port);my_addr.sin_addr.s_addr=htonl(INADDR_ANY);printf("Binding server to port %d\n",port);int err_log = bind(sockfd,(struct sockaddr *)&my_addr,sizeof(my_addr));if(err_log!=0){printf("bind error!\n");close(sockfd);exit(-1);}err_log = listen(sockfd, 1000);if(err_log != 0){perror("listen");close(sockfd);		exit(-1);}printf("listen client @port=%d...\n",port);while(1){int count=0;char recv_buf[128] = "";struct sockaddr_in client_addr;char cli_ip[INET_ADDRSTRLEN] = "";socklen_t cliaddr_len = sizeof(client_addr);int connfd = accept(sockfd, (struct sockaddr*)&client_addr, &cliaddr_len);       if(connfd < 0){perror("accept");continue;}inet_ntop(AF_INET, &client_addr.sin_addr, cli_ip, INET_ADDRSTRLEN);recv(connfd, recv_buf, sizeof(recv_buf), 0);if(strcmp(recv_buf, "ok") != 0){printf("recv error by %s\n", recv_buf);}pthread_mutex_lock(&connect_mutex);fd_list[fd_count] = connfd;fd_count++;pthread_mutex_unlock(&connect_mutex);printf("thread%d ip:%s, port:%d, connfd:%d, fd_count:%d\n",port, cli_ip, ntohs(client_addr.sin_port), connfd, fd_count);}close(sockfd);return NULL;}
    int main(int argc, char *argv[]){pthread_t pid1, pid2;uint16_t port1 = 10000;uint16_t port2 = 10001;pthread_mutex_init(&connect_mutex, NULL);pthread_create(&pid1, NULL, connect_thread, (void*)port1);pthread_create(&pid2, NULL, connect_thread, (void*)port2);pthread_join(pid1, NULL);pthread_join(pid2, NULL);return 0;
    }
  2. 客户端代码: tcpclient.c

    #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>
    #include <sys/time.h>
    #include <pthread.h>static int connect_total = 1;
    typedef struct {pthread_t pid;uint16_t port;uint32_t duration;
    }th_info_t;
    uint64_t clocktime_now() {struct timespec ts;clock_gettime(CLOCK_MONOTONIC,&ts);return ts.tv_sec * 1000000 + ( ts.tv_nsec / 1000 );
    }void* connect_thread(void* arg){char server_ip[16] = "192.168.1.108";int connect_num = (connect_total+1)/2;int connect_idx = 0;th_info_t* th_info = (th_info_t*)arg;printf("thread%d connect_num:%d\n", th_info->port, connect_num);uint64_t start_time = clocktime_now();while(connect_idx < connect_num){connect_idx++;uint64_t start = clocktime_now();int sockfd = socket(AF_INET, SOCK_STREAM, 0);if(sockfd < 0){printf("sockfd error!\n");exit(-1);}struct sockaddr_in dest_addr;memset(&dest_addr, 0, sizeof(dest_addr));dest_addr.sin_family = AF_INET;dest_addr.sin_port = htons(th_info->port);inet_pton(AF_INET, server_ip, &dest_addr.sin_addr);int err_log = connect(sockfd, (struct sockaddr*)&dest_addr, sizeof(dest_addr));      // 主动连接服务器if(err_log != 0){perror("connect");close(sockfd);exit(-1);}int ret = send(sockfd, "ok", strlen("ok"), 0);printf("thread%d connect fd:%d count:%d, ts:%dus\n", th_info->port, sockfd, connect_idx, clocktime_now()-start);}th_info->duration = (clocktime_now()-start_time)/1000;return NULL;
    }
    int main(int argc, char *argv[]){th_info_t th_info1, th_info2;th_info1.port = 10000;th_info2.port = 10001;if(argc >= 2){connect_total = atoi(argv[1]);}pthread_create(&th_info1.pid, NULL, connect_thread, (void*)&th_info1);pthread_create(&th_info2.pid, NULL, connect_thread, (void*)&th_info2);pthread_join(th_info1.pid, NULL);pthread_join(th_info2.pid, NULL);printf("thread%d connect success duration:%dms\n", th_info1.port, th_info1.duration);printf("thread%d connect success duration:%dms\n", th_info2.port, th_info2.duration);sleep(10);return 0;
    }
  3. 编译脚本: make-linux.sh

    #!/bin/bash
    gcc -o server tcpserver.c -lpthread
    gcc -o client tcpclient.c -lpthread

三、编译测试

  1. 将服务代码、客户端代码、编译脚本放入同一个目录
  2. ./make-linux.sh
  3. 测试
    • 第一次测试:客户端建立40000连接,平均到10000和10001端口
      结果:每次连接完成20us(微妙)左右
    • 第二次测试:客户端建立33000连接,只连接到10000端口
      结果:前32255个连接,每个连接20us(微妙)左右;后745个连接,每个连接完成3400us(微妙)左右
  4. 结论
    • 单个socket的连接数超过最大值32255后,每个连接的完成耗时变大
    • 为什么是32255?net.ipv4.ip_local_port_range设置端口范围 (65535-1024)/2=3225.5 ,至于为什么是超过范围量的二分之一变慢(改变范围,测出的结果),还没找到答案

四、解决方案

  1. 服务端在单进程情况,想要提高连接数的效率,目前想到的方案:多线程监听多个端口

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux用户和用户组的操作

用户管理 以Tom做为用户名 以dev做为用户组 增加用户 sudo adduser Tom #不建议使用useradd/userdel系列的命令删除用户 sudo deluser Tom --remove-home # 删除Tom用户及home目录 重置密码 sudo passwd Tom加入用户组 sudo usermod -a -G dev Tom # sudo usermod -aG …

STM32自己从零开始实操04:显示电路原理图

一、TFT-LCD 屏接口 1.1指路 以下是该部分的设计出来后的实物图&#xff0c;我觉得看到实物图可能更方便理解这部分的设计。 图1 实物图 这部分设计的是一个屏幕的接口&#xff0c;很简单。使用的屏幕是&#xff1a;2.8inch 16BIT Module MRB2801。 1.2数据手册 &#xff0…

Python汉化安装全攻略:深度解析与实战挑战

Python汉化安装全攻略&#xff1a;深度解析与实战挑战 在编程的世界里&#xff0c;Python以其简洁易懂的语法和强大的功能库赢得了众多开发者的青睐。然而&#xff0c;对于非英语母语的初学者来说&#xff0c;语言障碍可能成为一个不小的挑战。因此&#xff0c;Python的汉化安…

uinty游戏界面模糊的解决方法

1.把低分辨率关掉 2.调缩放&#xff0c;不要调长宽高 3.调整画布的分辨率 4.调整图片的像素点

如何恢复永久删除的照片?

“嗨&#xff0c;我永久删除了电脑上的很多照片。回收站被清空&#xff0c;照片会永久丢失吗&#xff1f;有什么方法可以恢复这些已删除的照片吗&#xff1f; 我们所有人都经历过同样的事情&#xff1a;我们的硬盘上存储了文件、视频或照片&#xff0c;但不小心删除了它。这个…

短信API接口相比邮件API接口的优缺点对比?

API接口怎么做开发集成&#xff1f;如何保障API接口的安全性&#xff1f; 短信API接口和邮件API接口作为两种主要的通信方式&#xff0c;各有其独特的优缺点。接下来&#xff0c;Aok将对这两种接口进行详细的对比分析&#xff0c;并特别提及AokSend邮件API的优点。 短信API接…

css实现不同设备适配

CSS可以通过媒体查询&#xff08;Media Queries&#xff09;来实现不同设备的适配。媒体查询可以根据设备的特性&#xff0c;如屏幕尺寸、分辨率等&#xff0c;来应用不同的样式规则。 以下是一些常见的方法来实现不同设备的适配&#xff1a; 1. **使用媒体查询** - 通过在CSS中…

最大堆,最小堆,优先队列,堆排序 LC例题-找第K大元素

LC215 数组中的第K个最大元素 class Solution {static Comparator<Integer> cmp new Comparator<Integer>(){Overridepublic int compare(Integer i1, Integer i2){return i1 - i2;//升序排列// return i2 - i1&#xff1b;//降序}}; public static int findKthL…

湖南(品牌定位)源点咨询 企业如何选择品牌定位差异化调研

湖南源点认为&#xff1a;精准且占据消费者认知&#xff0c;探寻与消费者共鸣的常态化品牌定位调研是企业品牌长远健康发展的基石。 品牌定位里要强调品牌的差异。英文是point of difference. 这个差异点就是强调品牌能带来的利益&#xff08;benefit&#xff09;。 这个“利…

【NoSQL数据库】Redis命令、持久化、主从复制

Redis命令、持久化、主从复制 redis配置 Redis命令、持久化、主从复制Redis数据类型redis数据库常用命令redis多数据库常用命令1、多数据库间切换2、多数据库间移动数据3、清除数据库内数据 key命令1、keys 命令2、判断键值是否存在exists3、删除当前数据库的指定key del4、获取…

记录layui-table中操作列的宽度随着权限变化而变化

最近做一个项目&#xff0c;某个页面因为角色不同&#xff0c;所以显示的的按钮有所不同。 管理员权限 普通人员权限 layui引入的table宽度是写死的&#xff0c;不能随着自动变化&#xff0c;查了一些资料&#xff0c;让写入css的方法 .layui-table th, .layui-table td { whi…

[MYSQL]销售分析III

表&#xff1a; Product ----------------------- | Column Name | Type | ----------------------- | product_id | int | | product_name | varchar | | unit_price | int | ----------------------- product_id 是该表的主键&#xff08;具有唯一值的列&am…

【JavaScript脚本宇宙】深入JavaScript文件上传库: 功能与应用一网打尽

模块化轻量级的文件上传&#xff1a;未来的趋势 前言 在这个时代&#xff0c;我们的生活和工作都离不开文件上传。为了解决文件上传问题&#xff0c;许多优秀的JavaScript库被创造出来。本文将详细介绍六个不同的JavaScript文件上传库&#xff0c;包括它们的概述、主要特性、…

LabVIEW的大气环境实时监测

LabVIEW的大气环境实时监测 设计并实现了一个基于LabVIEW的大气环境实时监测系统。通过使用高精度环境传感器采集温度、湿度、PM2.5、CO2等环境数据&#xff0c;利用LabVIEW进行数据处理、显示和存储。该系统能够实时监控环境参数&#xff0c;并通过阈值报警功能提示异常&…

Linux中,ll 命令 列出目录的内容

文章目录 1、2、3、4、5、 1、 在Linux中&#xff0c;ll 通常是一个别名&#xff08;alias&#xff09;用于 ls -l 命令。ls 命令用于列出目录的内容&#xff0c;而 -l 选项会以长格式&#xff08;long format&#xff09;显示信息&#xff0c;包括文件或目录的权限、所有者、…

E.小绿的房子[牛客周赛45][二维vector存图巧解]

题目描述 B市的地图是一棵有nn个节点的树&#xff0c;每个节点上都有房子出售。小棕和小绿是一对好朋友&#xff0c;他们近期都准备在B市买房。为了方便周末一起玩&#xff0c;小绿希望他的房子一定不要离小棕的太远。不过为了给小棕一个惊喜&#xff0c;小绿没有去找小棕问他买…

MATLAB cell数组 (tuple)

创建cell数组:访问和修改cell数组:遍历cell数组:转换cell数组:cell数组函数:删除cell数组中的元素:总结 MATLAB中的 cell数组是一种特殊类型的数组&#xff0c;可以用来存储不同类型和大小的数据。与一般的数值数组不同&#xff0c; cell数组可以包含不同类型的数据&#xff…

【SITS_CC】卫星图像时间序列的变化字幕(IEEE GRSL)

摘要 Satellite images time series (SITS) 提供了一种有效的方法来同时获取地球上观测区域的时间和空间信息。然而&#xff0c;传统的遥感CD方法的输出是二进制图或语义变化图&#xff0c;往往难以被最终用户解释&#xff0c;传统的遥感图像变化字幕方法只能描述双时图像。提…

微信,qt6953188,添 加 频繁怎么办?分享5种解决方案!

最近不少朋友反馈一个问题&#xff0c;就是微 信&#xff0c;qt6953188 添 加 频繁&#xff0c;想要联系的时候&#xff0c;加不上&#xff0c;不知道怎么办&#xff1f;也有因为添加不上&#xff0c;结果造成了一定的损失。 在2021年的时候&#xff0c;一位北京的朋友添 加…

【python】成功解决“ModuleNotFoundError: No module named ‘timm’”错误的全面指南

成功解决“ModuleNotFoundError: No module named ‘timm’”错误的全面指南 一、引言 在Python编程中&#xff0c;经常会遇到各种导入模块的错误&#xff0c;其中“ModuleNotFoundError: No module named ‘timm’”就是一个典型的例子。这个错误意味着你的Python环境中没有安…