【网络编程开发】10.UNIX套接字域

10.UNIX套接字域

UNIX域套接字是用于在同一台计算机上运行的进程之间进行通信的一种机制。它与传统基于TCP/IP协议栈的套接字不同,UNIX域套接字操作更为高效,因为它避免了网络层的开销,不涉及网络报头、检验和、顺序号等复杂的网络协议处理过程。UNIX域套接字的特点包括:

  1. 高效的本地通信:由于不需要网络层面的处理,UNIX域套接字在本地进程间通信时比使用TCP套接字更高效。
  2. 路径名作为地址:UNIX域套接字使用文件系统中的路径名作为地址,创建套接字时会在文件系统相应位置创建一个类型为套接字的文件。
  3. 两种类型的套接字:UNIX域套接字提供流式(SOCK_STREAM)和数据包式(SOCK_DGRAM)两种类型的套接字,且都是可靠的。
  4. 权限问题:绑定UNIX域套接字时,调用进程需要有对应目录部分的可写权限,并且默认情况下,创建的文件具有777的权限。
  5. 抽象路径名:Linux特有的特性,允许将UNIX域套接字绑定到一个名字上,而不会实际在文件系统中创建文件。
  6. 传递文件描述符:UNIX域套接字可以在同一台主机上的各进程之间传递文件描述符。
  7. 编程接口:虽然API调用方式与TCP/IP套接字类似,但在UNIX域套接字中,地址是以sockaddr_un结构体来表示的。

流式和数据包式的区别

特性流式 SOCK_STREAM数据包式 SOCK_DGRAM
连接方式面向连接(TCP协议)无连接(UDP协议)
可靠性高(错误检测和重传机制)低(无错误检测和重传)
数据传输方式字节流(可能分段)数据报文(独立单位)
资源消耗较大(维护连接状态)较小(无需维护连接)
处理速度较慢(保证可靠性)较快(不保证可靠性)
适用场景文件传输、远程登录等音视频传输、广播消息等
网络环境适应性适用于稳定网络环境适用于局域网或实时性要求高的环境

UNIX流式套接字

示例代码

在Linux终端输入命令:man bind 滑到下面查看示例代码

在这里插入图片描述

复制示例代码并稍作修改

服务端

UNIX_sever.c

#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>#define MY_SOCK_PATH "/tmp/my_sock_file" // 套接字文件地址
#define LISTEN_BACKLOG 50 // 监听队列长度#define handle_error(msg) \n	do { perror(msg); exit(EXIT_FAILURE); } while (0) // 错误处理宏int main(int argc, char *argv[])
{int sfd, cfd; // 服务器套接字描述符和客户端套接字描述符struct sockaddr_un my_addr, peer_addr; // 地址结构体socklen_t peer_addr_size; // 客户端地址结构体大小char buf[BUFSIZ] = {}; // 缓冲区sfd = socket(AF_UNIX, SOCK_STREAM, 0); // 创建套接字if (sfd == -1)handle_error("socket"); // 错误处理memset(&my_addr, 0, sizeof(struct sockaddr_un)); // 清空地址结构体my_addr.sun_family = AF_UNIX; // 设置地址类型为AF_UNIXstrncpy(my_addr.sun_path, MY_SOCK_PATH, sizeof(my_addr.sun_path) - 1); // 设置套接字文件路径if (bind(sfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_un)) == -1) // 绑定套接字handle_error("bind"); // 错误处理if (listen(sfd, LISTEN_BACKLOG) == -1) // 监听套接字handle_error("listen"); // 错误处理peer_addr_size = sizeof(struct sockaddr_un); // 获取客户端地址结构体大小cfd = accept(sfd, (struct sockaddr *) &peer_addr, &peer_addr_size); // 接受客户端连接if (cfd == -1)handle_error("accept"); // 错误处理recv(cfd, buf, BUFSIZ, 0); // 接收客户端发送的数据printf("buf = %s\n", buf); // 打印接收到的数据close(cfd); // 关闭客户端套接字close(sfd); // 关闭服务器套接字return 0;
}
  1. 编译:gcc -o UNIX_sever UNIX_sever.c -Wall
  2. 运行:./UNIX_sever
  3. 结束运行:ctrl+c
  4. 再次运行:./UNIX_sever报错,bind: Address already in use

在这里插入图片描述

  1. 删除套接字文件:rm /tmp/my_sock_file
  2. 再次运行:./UNIX_sever,报错消失
  3. 原因:ctrl+c 强制结束没有执行remove(MY_SOCK_PATH); 所以要手动删除

客户端

#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>#define MY_SOCK_PATH "/tmp/my_sock_file"//套接字文件地址#define handle_error(msg) \n	do { perror(msg); exit(EXIT_FAILURE); } while (0)int main(int argc, char *argv[])
{int fd; // 文件描述符struct sockaddr_un peer_addr; // UNIX域套接字地址结构体char buf[BUFSIZ] = {"Hello World"}; // 发送缓冲区fd = socket(AF_UNIX, SOCK_STREAM, 0); // 创建套接字if (fd == -1)handle_error("socket"); // 错误处理memset(&peer_addr, 0, sizeof(struct sockaddr_un)); // 清空地址结构体peer_addr.sun_family = AF_UNIX; // 设置地址类型为AF_UNIXstrncpy(peer_addr.sun_path, MY_SOCK_PATH, sizeof(peer_addr.sun_path) - 1); // 设置套接字文件路径if (connect(fd, (struct sockaddr *) &peer_addr, sizeof(struct sockaddr_un)) == -1) // 连接服务器handle_error("connect"); // 错误处理send(fd, buf, strlen(buf), 0); // 发送数据close(fd); // 关闭套接字remove(MY_SOCK_PATH); // 删除套接字文件return 0;
}

在这里插入图片描述

UNIX数据包式套接字

服务端

#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>#define MY_SOCK_PATH "/tmp/my_sock_file"
#define handle_error(msg) \n	do { perror(msg); exit(EXIT_FAILURE); } while (0)int main(int argc, char *argv[])
{int fd;struct sockaddr_un my_addr, peer_addr;socklen_t peer_addr_size;char buf[BUFSIZ] = {};// 创建UDP套接字fd = socket(AF_UNIX, SOCK_DGRAM, 0);if (fd == -1)handle_error("socket");// 清空地址结构体并设置类型和路径memset(&my_addr, 0, sizeof(struct sockaddr_un));my_addr.sun_family = AF_UNIX;strncpy(my_addr.sun_path, MY_SOCK_PATH,sizeof(my_addr.sun_path) - 1);// 绑定套接字到指定路径if (bind(fd, (struct sockaddr *) &my_addr,sizeof(struct sockaddr_un)) == -1)handle_error("bind");// 接收数据并打印peer_addr_size = sizeof(struct sockaddr_un);recvfrom(fd, buf, BUFSIZ, 0, (struct sockaddr *) &peer_addr,&peer_addr_size);printf("%s\n",buf);// 关闭套接字并删除文件close(fd);remove(MY_SOCK_PATH);return 0;
}

客户端

#include <sys/socket.h> 
#include <sys/un.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <unistd.h> #define MY_SOCK_PATH "/tmp/my_sock_file" // 定义套接字文件路径
#define handle_error(msg) \n	do { perror(msg); exit(EXIT_FAILURE); } while (0) // 定义错误处理宏int main(int argc, char *argv[]) 
{int fd; // 文件描述符struct sockaddr_un peer_addr; // UNIX域套接字地址结构体socklen_t peer_addr_size; // UNIX域套接字地址大小char buf[BUFSIZ] = {"Hello World!"}; // 发送缓冲区fd = socket(AF_UNIX, SOCK_DGRAM, 0); // 创建UDP套接字if (fd == -1)handle_error("socket"); memset(&peer_addr, 0, sizeof(struct sockaddr_un)); // 清空地址结构体peer_addr.sun_family = AF_UNIX; // 设置地址类型为AF_UNIXstrncpy(peer_addr.sun_path, MY_SOCK_PATH,sizeof(peer_addr.sun_path) - 1); // 设置套接字文件路径peer_addr_size = sizeof(struct sockaddr_un); // 获取地址大小printf("%s\n", buf); // 打印发送缓冲区内容sendto(fd, buf, strlen(buf), 0, (struct sockaddr *) &peer_addr,peer_addr_size); // 向服务器发送数据close(fd); // 关闭套接字remove(MY_SOCK_PATH); // 删除套接字文件return 0; 
}

在这里插入图片描述

通信成功

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

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

相关文章

ANSYS APDL中使用SF和SFFUN命令,对不同节点施加不同大小的面载荷

SF命令通常是对 所选择的节点集合 施加同样大小的载荷&#xff0c;如&#xff1a; NSEL, S, LOC, Y, 5 ! 选择y坐标值为5的全部结点 SF, ALL, PRES, 1 ! 施加均布荷载 完整命令流&#xff1a; Finish !退出当前处理器 /Clear,al…

websocket发送数据

1. 使用JSON格式传输参数 可以使用库如Jackson或Gson来处理JSON。 客户端发送JSON消息&#xff1a; var socket new WebSocket("ws://localhost:8080/ws"); socket.onopen function() {var message {"action": "greet","name": …

tensorRT 自定义算子plugin的实现

文章目录 1. 自定义算子导出onnx1.1 自定义算子的实现类1.2 自定义算子类1.3 onnx导出2. 自定义算子plugin的实现2.1 Plugin类的实现2.1.1 构造函数的实现2.1.2 析构函数实现2.1.3 serialize函数的实现2.1.4 destory函数的实现2.1.5 enqueue函数的实现(关键)2.1.5.1 customSc…

C#操作MySQL从入门到精通(16)——使用子查询

前言: 我们在查询数据的过程中有时候查询的数据不是从数据库中来的,而是从另一个查询的结果来的,这时候就需要使用子查询,本文使用的测试数据如下: 1、子查询 下面的代码就是先查询地址是安徽和广西的学生年龄,然后获取年龄对应的姓名 private void button__SubQuery…

Spring boot+vue前后端分离

目录 1、前端vue的搭建 2、后端项目的构建 pom文件中引入的jar包 yml文件用来配置连接数据库和端口的设置 application.property进行一些整合 service层 imp层 mapper 实体类 额外写一个类、解决跨域问题 3、测试 1、前端vue的搭建 建立项目的过程略 开启一个建立好…

【SZUOJ】【高精度板子】E. 大整数计算(运算符重载)

被学校oj的高精度恶心到了&#xff0c;所以我觉得以后把它当板子 //??CBigInteger????? /********** Write your code here! **********/ #include<bits/stdc.h> using namespace std; class CBigInteger { public:vector<int> a;int si;CBigInteger(){si1…

用自然语言连接信息孤岛

信息孤岛互联互通的困难 尽管已经进入了互联网时代&#xff0c;信息系统中的信息孤岛现象仍然十分地严重&#xff0c;不同部门&#xff0c;不同机器之间难以实现信息的互联互通。存在大量的信息孤岛。 不同信息系统的相互通信依赖通信协议和数据模型的定义&#xff0c;前者决定…

上海安全员C证继续教育题库(附答案)

1.从业人员经过安全教育培训&#xff0c;了解岗位操作规程&#xff0c;但未遵守而造成事故的&#xff0c;行为人应负( )责任&#xff0c;有关负责人应负( )责任。 A.直接 间接 B.直接 领导 C.间接 管理D.直接 管理 2.对生产附着式升降脚手架产品的单位&#xff0c;必须…

Java数据结构与算法(买卖股票最佳时机​)

前言 买卖股票最佳时机和最长子数组和类似。暴力算法和动态规划算法几乎如出一辙。一个是前序和小于零时重置当前值&#xff0c;一个是最小值小于当前值时重置为最小值。需关注重置的计算规则和标志。 买卖股票对应leetcode . - 力扣&#xff08;LeetCode&#xff09; 实现…

一定要了解的 WordPress 数据库中默认 12 个表

WordPressan 安装的时候会有 12 张默认的数据表,每张表的数据都包含了 WordPress 不同的功能。看看这些表的结构,你能很容易的了解网站不同的部分都是存在哪里的。目前,默认的 WordPress 安装会创建如下的数据表。 注意:每张表名前面的 wp_ 是你在安装过程中选择的数据库前…

LeetCode 9 - 回文数

给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。 例如&#xff0c;121 是回文&#xff0c;而…

【IoT NTN】3GPP R18中关于各类IoT设备在NTN中的增强和扩展

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G技术研究。 博客内容主要围绕…

vue调用百度api时跨域问题的解决方案

最近在开发一个基于百度图片文字识别的功能&#xff0c;本来在后端调用百度api的接口&#xff0c;功能已经完成了&#xff0c;但是由于后端服务器不能访问外网&#xff0c;所以将调用百度api的功能需要移到前端&#xff0c;于是就一个坑接一个坑&#xff0c;好不容易开发完成&a…

Flink 入门案例介绍

一、工程搭建 在 IDEA 中创建一个 Maven 工程&#xff1a;FlinkTutorial 在 pom 文件中引入依赖&#xff1a; <dependencies><dependency><groupId>org.apache.flink</groupId><artifactId>flink-java</artifactId><version>1.10.1…

SAP ABAP 往数据库表里加数据

目录 方法一&#xff1a;SE16N SE11 方法二&#xff1a;创建维护VIEW&#xff1a;SE11 SM30 Error补充说明&#xff1a; 方法一&#xff1a;SE16N SE11 首先SE16N 进来。 进来之后在テーブル的位置输入表名&#xff0c;然后点击执行&#xff08;F8&#xff09; 如果第一次…

spring 解决循环依赖

在 spring 框架中&#xff0c;我们知道它是通过三级缓存来解决循环依赖的&#xff0c;那么它具体是怎么实现的&#xff0c;以及是否必须需要三级缓存才能解决循环依赖&#xff0c;本文来作相关介绍。 具体实现 先来看看它的三级缓存到底是什么&#xff0c;先看如下代码&#…

Unity动画录制工具在运行时录制和保存模型骨骼运动的方法录制动画给其他角色模型使用支持JSON、FBX等格式

如果您正在寻找一种在运行时录制和保存模型骨骼运动的方法&#xff0c;那么此插件是满足您需求的完美解决方案。 实时录制角色运动 将录制到的角色动作转为动画文件 将录制好的动作给新的角色模型使用&#xff0c;完美复制 支持导出FBX格式 操作简单&#xff0c;有按钮界面…

selenium的使用教程

Selenium简介 Selenium是一个用于Web应用程序自动化测试工具。它支持多种浏览器&#xff0c;可以录制、编辑和运行自动化测试。通过Selenium&#xff0c;我们可以编写脚本来模拟用户在浏览器中的操作&#xff0c;从而进行功能测试。 二、安装与配置 安装Selenium库 使用pip安…

unity中通过实现底层接口实现非按钮(图片)的事件监听

编写监听脚本 PEListenter 继承自MonoBehaviour类&#xff0c;并实现了IPointerDownHandler、IPointerUpHandler和IDragHandler接口&#xff0c;按照需求定义需要接收事件&#xff08;鼠标按下、抬起、拖拽&#xff09;的回调函数 //监听类&#xff08;需要挂载在物体上面&am…

关于AD9777芯片的说明以及FPGA控制实现 I

关于AD9777芯片的说明以及FPGA控制实现 I 语言 :Verilg HDL 、VHDL EDA工具:ISE、Vivado、Quartus II 关于AD9777芯片的说明以及FPGA控制实现 I一、引言二、AD9777主要特色1. 高分辨率和高速数据率:2. 可编程插值滤波器:3. 数字正交调制能力:4. 低功耗:5. SPI接口:6. 内…