AF_UNIX和127.0.0.1(AF_INET)回环地址写数据速度对比(二)
之前写了篇博客:AF_UNIX和127.0.0.1(AF_INET)回环地址写数据速度对比
然后利用的是发送端读取大文件,接收方接收并保存为文件的方式进行测试,结果发现,AF_UNIX并未比127.0.0.1(AF_INET)回环地址优秀,若单次发送的字节数少时,回环地址反而更快。
由于测试时发送的是1.15G大小的文件,比较快就发送结束了,而且读文件,写文件是个比较费时的操作,本人考虑到读写文件费时的影响,决定发送端自己构造字符串,接收方只统计接收到的字符个数,并不写文件。然后发送端发送100秒,对比下100秒之内,AF_UNIX和回还地址接收到的字节个数。
AF_UNIX服务端代码(unixsocketserver2.c)
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h> #define MAXLINE 80 char *socket_path = "/tmp/server.socket"; #define RECV_LEN 1000000int main(void)
{ fd_set readmask, exceptmask;struct timeval tv;int maxfd = FD_SETSIZE;int nready = 0;char buf[RECV_LEN + 1];int readbyte, writebyte;struct sockaddr_un serun, cliun; socklen_t cliun_len; int listenfd, connfd, size; if ((listenfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { perror("socket error"); exit(1); } long long allrecvbyte = 0;memset(&serun, 0, sizeof(serun)); serun.sun_family = AF_UNIX; strcpy(serun.sun_path, socket_path); size = offsetof(struct sockaddr_un, sun_path) + strlen(serun.sun_path); unlink(socket_path); if (bind(listenfd, (struct sockaddr *)&serun, size) < 0) { perror("bind error"); exit(1); } printf("UNIX domain socket bound\n"); if (listen(listenfd, 20) < 0) { perror("listen error"); exit(1); } printf("Accepting connections ...\n"); cliun_len = sizeof(cliun); if ((connfd = accept(listenfd, (struct sockaddr *)&cliun, &cliun_len)) < 0){ perror("accept error"); goto end; }time_t now, endtime;now = time(NULL);while(1){FD_ZERO(&readmask);FD_ZERO(&exceptmask);FD_SET(connfd, &readmask);FD_SET(connfd, &exceptmask);tv.tv_sec = 3;tv.tv_usec = 0;nready = select(maxfd, &readmask, NULL, &exceptmask, &tv);if(nready < 0){goto end;}if(nready == 0){printf("nready == 0\n");continue;}if(FD_ISSET(connfd, &readmask)){readbyte = recv(connfd, buf, RECV_LEN, 0);if(readbyte < 0){perror("readbyte < 0");goto end;}if(readbyte == 0){perror("readbyte == 0");goto end;}if(readbyte > 0){allrecvbyte += readbyte;}}if(FD_ISSET(connfd, &exceptmask)){printf("select, exceptmask\n");goto end;}}
end:endtime = time(NULL);printf("costs %d seconds, allrecvbyte is %lld\n", endtime - now, allrecvbyte);close(connfd);close(listenfd); return 0;
}
AF_UNIX客户端代码(unixsocketclient2.c)
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <string.h>
#include <unistd.h> #define SEND_LEN 1000000char *client_path = "/tmp/client.socket";
char *server_path = "/tmp/server.socket"; int main() { struct sockaddr_un cliun, serun; int len; int sockfd, n; int i = 0;if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){ perror("client socket error"); exit(1); } // 一般显式调用bind函数,以便服务器区分不同客户端 memset(&cliun, 0, sizeof(cliun)); cliun.sun_family = AF_UNIX; strcpy(cliun.sun_path, client_path); len = offsetof(struct sockaddr_un, sun_path) + strlen(cliun.sun_path); unlink(cliun.sun_path); if (bind(sockfd, (struct sockaddr *)&cliun, len) < 0) { perror("bind error"); exit(1); } memset(&serun, 0, sizeof(serun)); serun.sun_family = AF_UNIX; strcpy(serun.sun_path, server_path); len = offsetof(struct sockaddr_un, sun_path) + strlen(serun.sun_path); if (connect(sockfd, (struct sockaddr *)&serun, len) < 0){ perror("connect error"); exit(1); } int sendbyte = 0;int alreadysendbyte = 0;long long allsendbyte = 0;char buf[SEND_LEN + 1];time_t begin = time(NULL);time_t now = time(NULL);int continueSeconds = 0;while(continueSeconds < 100){alreadysendbyte = 0;for(i = 0; i < SEND_LEN; i++){buf[i] = i + 1;}n = SEND_LEN;sendbyte = send(sockfd, buf, n, 0);if(sendbyte == -1){perror("send error");goto end;}alreadysendbyte += sendbyte;while(alreadysendbyte < n){sendbyte = send(sockfd, buf + alreadysendbyte, n - alreadysendbyte, 0);if(sendbyte == -1){perror("send error");goto end;}alreadysendbyte += sendbyte;}allsendbyte += n;now = time(NULL);continueSeconds = now - begin;}
end:printf("allsendbyte is %lld\n", allsendbyte);close(sockfd);return 0;
}
回环地址服务端代码(loopaddrserver2.c)
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>#define RECV_LEN 1000000int main(){fd_set readmask, exceptmask;struct timeval tv;int maxfd = FD_SETSIZE;int nready = 0;char buf[RECV_LEN + 1];int readbyte, writebyte;int serv_sock=socket(AF_INET,SOCK_STREAM,0);long long allrecvbyte = 0;struct sockaddr_in serv_addr;memset(&serv_addr,0,sizeof(serv_addr));serv_addr.sin_family=AF_INET;serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);serv_addr.sin_port=htons(9990);bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr));listen(serv_sock,5);struct sockaddr_in clnt_addr;socklen_t clnt_addr_size=sizeof(clnt_addr);int clnt_sock=accept(serv_sock,(struct sockaddr*)&clnt_addr,&clnt_addr_size);time_t now, endtime;now = time(NULL);while(1){FD_ZERO(&readmask);FD_ZERO(&exceptmask);FD_SET(clnt_sock, &readmask);FD_SET(clnt_sock, &exceptmask);tv.tv_sec = 3;tv.tv_usec = 0;nready = select(maxfd, &readmask, NULL, &exceptmask, &tv);if(nready < 0){goto end;}if(nready == 0){printf("nready == 0\n");continue;}if(FD_ISSET(clnt_sock, &readmask)){readbyte = recv(clnt_sock, buf, RECV_LEN, 0);if(readbyte < 0){perror("readbyte < 0");goto end;}if(readbyte == 0){perror("readbyte == 0");goto end;}if(readbyte > 0){allrecvbyte += readbyte;}}if(FD_ISSET(clnt_sock, &exceptmask)){printf("select, exceptmask\n");goto end;}}
end: endtime = time(NULL);printf("costs %d seconds, allrecvbyte is %lld\n", endtime - now, allrecvbyte);close(clnt_sock);close(serv_sock);return 0;
}
回环地址客户端代码(loopaddrclient2.c)
#include<sys/socket.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<string.h>
#include <errno.h>
#include <stdlib.h>#define SEND_LEN 1000000int main(){int sock=socket(AF_INET,SOCK_STREAM,0); int n = 0;int i = 0;struct sockaddr_in serv_addr;memset(&serv_addr,0,sizeof(serv_addr));serv_addr.sin_family=AF_INET;serv_addr.sin_addr.s_addr=inet_addr("127.0.0.1");serv_addr.sin_port=htons(9990);if(connect(sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) < 0){perror("connect failed");goto end;}int sendbyte = 0;int alreadysendbyte = 0;long long allsendbyte = 0;char buf[SEND_LEN + 1];time_t begin = time(NULL);time_t now = time(NULL);int continueSeconds = 0;while(continueSeconds < 100){alreadysendbyte = 0;for(i = 0; i < SEND_LEN; i++){buf[i] = i + 1;}n = SEND_LEN;sendbyte = send(sock, buf, n, 0);if(sendbyte == -1){perror("send error");goto end;}alreadysendbyte += sendbyte;while(alreadysendbyte < n){sendbyte = send(sock, buf + alreadysendbyte, n - alreadysendbyte, 0);if(sendbyte == -1){perror("send error");goto end;}alreadysendbyte += sendbyte;}allsendbyte += n;now = time(NULL);continueSeconds = now - begin;}
end:printf("allsendbyte is %lld\n", allsendbyte);close(sock);return 0;
}
测试结果:
单次send字节数为10000时,AF_UNIX接收字节数为30240650000,127.0.0.1(AF_INET)接收字节数为36394910000。
单次send字节数为100000时,AF_UNIX接收字节数为40230300000,127.0.0.1(AF_INET)接收字节数为38364400000。
单次send字节数为1000000时,AF_UNIX接收字节数为41368000000,127.0.0.1(AF_INET)接收字节数为42221000000。
可见,AF_UNIX比回环地址并无明显优势
相关文章:

AF_UNIX和127.0.0.1(AF_INET)回环地址写数据速度对比(二)
之前写了篇博客:AF_UNIX和127.0.0.1(AF_INET)回环地址写数据速度对比 然后利用的是发送端读取大文件,接收方接收并保存为文件的方式进行测试,结果发现,AF_UNIX并未比127.0.0.1(AF_INET)回环地址优秀,若单次发送的字节数…...

“Python+”集成技术高光谱遥感数据处理与机器学习教程
详情点击公众号链接:“Python”集成技术高光谱遥感数据处理与机器学习教程 第一:高光谱基础 一:高光谱遥感基本概念 01)高光谱遥感 02)光的波长 03)光谱分辨率 04)高光谱遥感的历史和发展 二:高光谱传感器与数据获取 01)高…...

centos7 快速搭建自测mysql环境 docker + mysql
环境准备 centos7快速搭建docker mysql docker镜像源配置 一般都是要配的不然太慢了,docker 1.12以上创建或修改 /etc/docker/daemon.json 文件,修改为如下形式: 地址替换国内源 {"registry-mirrors" : ["https://docker.mirrors.u…...

c++视觉检测-----Canny边缘算子
Canny边缘算子 cv::Canny()是OpenCV库中用于执行Canny边缘检测的函数。Canny边缘检测是一种广泛使用的图像处理技术,用于检测图像中的边缘。 以下是cv::Canny()函数的一般用法和参数: void cv::Canny(cv::InputArray image, // 输入图像&#x…...

机器学习笔记 - 用于动作识别的网络TSN/TSM/SlowFast/R(2+1)D/3D MobileNetV2
一、简述 动作识别是在视频序列中检测和分类人类动作的过程。 近年来,由于其广泛的应用,它已成为一项越来越重要的技术,例如监控、人机交互以及视频索引和检索。 特别是,动作识别对于无人驾驶飞行器 (UAV) 或无人机来说变得至关重要,因为它们越来越多地用于各种应用,例如…...

mybatis批量插入
一、定义DBExec import java.util.List;public abstract class DBExec<T> {public abstract void operate(List<T> list); }二、定义BatchDBService public interface BatchDBService<T> {void exec(int batchSize, List<T> list, DBExec<T> d…...

软件‘小程序‘前台开发软件定制的知识|app网站搭建
软件,小程序,前台开发软件定制的知识 随着互联网的快速发展,软件,小程序,前台开发软件定制已经成为了企业必备的工具。它可以帮助企业更好地管理业务,提高效率,增强用户体验。那么,什…...

HTML-注册页面
<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>注册页面</title> </head> <body><from action"#" method"get"><table border"1" align&q…...

17.(开发工具篇Gitlab)如何在Gitlab配置ssh key
前言: Git是分布式的代码管理工具,远程的代码管理是基于SSH的,所以要使用远程的Git则需要SSH的配置 一、git 配置 (1)打开 git 命令窗口 (2)配置用户名(填自己的姓名) git config --global user.name “chenbc” (3)配置用户邮箱(填自己的邮箱) git config …...

ArcGIS/GeoScene脚本:基于粒子群优化的支持向量机分类模型
参数输入 输出 栅格 预测为负类的概率 预测为正类的概率 二值化结果 评估结果 ROC曲线...

Python+Tkinter 图形化界面基础篇:添加图形和图像
PythonTkinter 图形化界面基础篇:添加图形和图像 引言添加图形元素步骤1:导入 Tkinter 步骤2:创建主窗口步骤3:创建 Canvas 步骤4:绘制图形 绘制线条 绘制矩形 绘制椭圆 绘制多边形 步骤5:启动主事件循环 显…...
前端js八股文大全
一、js的数据类型 值类型(基本类型):数字(Number)、字符串(String)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol,大数值类型(BigInt) 引用数据类型:对象(Object)、数组…...

[环境]Ubuntu20.04安装Ceres
安装这么顺利我有点不适应,记录一下 注意安装的位置与层级关系 参考链接 知乎方案...

ruoyi 若依 前端vue npm install 运行vue前端
首次导入,需要先执行 npm install #进入到前端模块目录下 cd ruoyi-ui # 安装 npm install 启动后端项目 运行前端项目:运行成功后,会浏览器自动加载到前端首页(或者 浏览器访问打印的两个地址) # 运行 npm run dev 部…...

各大搜索引擎的User-Agent
各大搜索引擎的User-Agent baidu:Mozilla/5.0 (compatible; Baiduspider/2.0; http://www.baidu.com/search/spider.html) Google:Mozilla/5.0 (compatible; Googlebot/2.1; http://www.google.com/bot.html) Sogou:Sogou web spider/4.0(h…...

codesys【按钮】
1用于控制bool信号。 1声明全局变量 2绑定该变量 运行后,按钮就能控制这个bool变量了。 2按钮【自复位】 3按钮【锁位】...

SSH在桌面会话启动应用程序
通过远程SSH会话在实体机(物理机)的当前登录用户的桌面会话上启动应用程序 1. 找到用户的桌面会话的DISPLAY变量 在大多数情况下,主桌面会话的DISPLAY变量设置为:0,但为了确定,你可以运行以下命令查找活跃的DISPLAY&…...

React的类式组件和函数式组件之间有什么区别?
React 中的类组件和函数组件是两种不同的组件编写方式,它们之间有一些区别。 语法和写法:类组件是使用类的语法进行定义的,它继承自 React.Component 类,并且需要实现 render() 方法来返回组件的 JSX。函数组件是使用函数的语法进…...

codesys【读写轴参数】
在SM3_Basic库内。 作用:读写实轴寄存器参数。【一般用于修改2000h段的值】 或者获取6041h的状态值。 ecat主站操作: 补偿间隙: 追剪: 凸轮: 读写轴参数:...

Java架构师系统架构设计确定系统边界
目录 2 初始业务场景分析2.1 业务的需求分析重要性2.2 全面深入的理解业务从零到一从无到有2.3 需求分析3 系统和系统边界定义3.1 为什么要确定系统边界3 需求分析明确系统边界4 高层架构设计4.1 技术架构4.2 部署架构4.3 安全架构4.4 存储架构5 高层架构设计确定系统边界5.1 和…...

pytorch实现经典神经网络:VGG16模型之初探
文章链接 https://blog.csdn.net/weixin_44791964/article/details/102585038?ops_request_misc%257B%2522request%255Fid%2522%253A%2522169675238616800211588158%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id16967523861680…...

Newtonsoft.Json use
private void button3_Click(object sender, EventArgs e) { List<Student> students new List<Student>(); students.Add(new Student { Id 1, Name "张三", Sex "男", Description "班长" }); students.…...

MySQL-3(9000字详解)
一:索引 索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现。 1.1索引的意义 索引的意义:加快查找速度,但需要…...

SLAM从入门到精通(3d 点云数据访问)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 3d 点云设备现在汽车上用的很多。之前3d lidar这种高端传感器,只能被少部分智能汽车使用。后来很多国产厂家也开始研发3d lidar之后&am…...

如何在 Spring Boot 中提高应用程序的安全性
如何在 Spring Boot 中提高应用程序的安全性 Spring Boot是一种流行的Java开发框架,用于构建Web应用程序和微服务。在构建应用程序时,安全性是至关重要的因素。不论您的应用程序是面向公众用户还是企业内部使用,都需要采取适当的措施来确保数…...

【Vuex+ElementUI】
一、导言 1、引言 Vuex是一个用于Vue.js应用程序的状态管理模式和库。它建立在Vue.js的响应式系统之上,提供了一种集中管理应用程序状态的方式。使用Vuex,您可以将应用程序的状态存储在一个单一的位置(即“存储”)中,…...

多媒体播放软件 Infuse mac中文特点介绍
Infuse mac是一款多媒体播放器应用,它支持播放多种格式的视频文件、音频文件和图片文件,并且可以通过AIrPlay将媒体内容投放到其他设备上。Infuse还支持在线视频流媒体播放和本地网络共享,用户可以通过它来访问家庭网络上的媒体文件。 Infuse…...

华为数通方向HCIP-DataCom H12-831题库(单选题:201-220)
第201题 如图所示,路由器所有的接口开启OSPF,链路的Cost值如图中标识。若在R2的OSPF进程中通过命令import-route direct type 1引入直连路由,则R1到达10.0.2.2 /32的Cost值是以下哪一选项? A、150 B、151 C、200 D、201 答案:C 解析: Loopback0的cost值默认为0,R1-R2的…...

【管理运筹学】第 9 章 | 网络计划(2,时间参数的计算 —— 工作时间的确定与事项的时间参数)
文章目录 引言一、工作时间的确定二、事项的时间参数2.1 事项的最早开始时间2.2 事项的最迟结束时间2.3 事项的时差2.4 利用事项的时间参数来确定关键线路 引言 计算网络图中有关的时间参数,主要目的是找到关键线路,为网络计划的优化、调增和执行提供明…...

英语——方法篇——单词——羊肉串记忆法——单词密码
在记忆英语单词的时候,我们习惯于一个字母一个字母地记忆,很少会以词或字母组合为单位来记忆。在这里我们要打开视野,学习以词或字母组合为单位,一组一组地记忆英语单词。英语单词数目庞大,但是构成单词的字母只有26个…...