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

2024-06-09 11:44
文章标签 开发 编程 网络 unix 接字

本文主要是介绍【网络编程开发】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; 
}

在这里插入图片描述

通信成功

这篇关于【网络编程开发】10.UNIX套接字域的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1045079

相关文章

【Linux进阶】UNIX体系结构分解——操作系统,内核,shell

1.什么是操作系统? 从严格意义上说,可将操作系统定义为一种软件,它控制计算机硬件资源,提供程序运行环境。我们通常将这种软件称为内核(kerel),因为它相对较小,而且位于环境的核心。  从广义上说,操作系统包括了内核和一些其他软件,这些软件使得计算机能够发挥作用,并使计算机具有自己的特生。这里所说的其他软件包括系统实用程序(system utility)、应用程序、shell以及公用函数库等

【Altium】查找PCB上未连接的网络

【更多软件使用问题请点击亿道电子官方网站】 1、文档目标: PCB设计后期检查中找出没有连接的网络 应用场景:PCB设计后期,需要检查是否所有网络都已连接布线。虽然未连接的网络会有飞线显示,但是由于布线后期整板布线密度较高,虚连,断连的网络用肉眼难以轻易发现。用DRC检查也可以找出未连接的网络,如果PCB中DRC问题较多,查找起来就不是很方便。使用PCB Filter面板来达成目的相比DRC

零基础STM32单片机编程入门(一)初识STM32单片机

文章目录 一.概要二.单片机型号命名规则三.STM32F103系统架构四.STM32F103C8T6单片机启动流程五.STM32F103C8T6单片机主要外设资源六.编程过程中芯片数据手册的作用1.单片机外设资源情况2.STM32单片机内部框图3.STM32单片机管脚图4.STM32单片机每个管脚可配功能5.单片机功耗数据6.FALSH编程时间,擦写次数7.I/O高低电平电压表格8.外设接口

16.Spring前世今生与Spring编程思想

1.1.课程目标 1、通过对本章内容的学习,可以掌握Spring的基本架构及各子模块之间的依赖关系。 2、 了解Spring的发展历史,启发思维。 3、 对 Spring形成一个整体的认识,为之后的深入学习做铺垫。 4、 通过对本章内容的学习,可以了解Spring版本升级的规律,从而应用到自己的系统升级版本命名。 5、Spring编程思想总结。 1.2.内容定位 Spring使用经验

通信系统网络架构_2.广域网网络架构

1.概述          通俗来讲,广域网是将分布于相比局域网络更广区域的计算机设备联接起来的网络。广域网由通信子网于资源子网组成。通信子网可以利用公用分组交换网、卫星通信网和无线分组交换网构建,将分布在不同地区的局域网或计算机系统互连起来,实现资源子网的共享。 2.网络组成          广域网属于多级网络,通常由骨干网、分布网、接入网组成。在网络规模较小时,可仅由骨干网和接入网组成

Eclipse+ADT与Android Studio开发的区别

下文的EA指Eclipse+ADT,AS就是指Android Studio。 就编写界面布局来说AS可以边开发边预览(所见即所得,以及多个屏幕预览),这个优势比较大。AS运行时占的内存比EA的要小。AS创建项目时要创建gradle项目框架,so,创建项目时AS比较慢。android studio基于gradle构建项目,你无法同时集中管理和维护多个项目的源码,而eclipse ADT可以同时打开

Toolbar+DrawerLayout使用详情结合网络各大神

最近也想搞下toolbar+drawerlayout的使用。结合网络上各大神的杰作,我把大部分的内容效果都完成了遍。现在记录下各个功能效果的实现以及一些细节注意点。 这图弹出两个菜单内容都是仿QQ界面的选项。左边一个是drawerlayout的弹窗。右边是toolbar的popup弹窗。 开始实现步骤详情: 1.创建toolbar布局跟drawerlayout布局 <?xml vers

Python应用开发——30天学习Streamlit Python包进行APP的构建(9)

st.area_chart 显示区域图。 这是围绕 st.altair_chart 的语法糖。主要区别在于该命令使用数据自身的列和指数来计算图表的 Altair 规格。因此,在许多 "只需绘制此图 "的情况下,该命令更易于使用,但可定制性较差。 如果 st.area_chart 无法正确猜测数据规格,请尝试使用 st.altair_chart 指定所需的图表。 Function signa

WDF驱动开发-WDF总线枚举(一)

支持在总线驱动程序中进行 PnP 和电源管理 某些设备永久插入系统,而其他设备可以在系统运行时插入和拔出电源。 总线驱动 必须识别并报告连接到其总线的设备,并且他们必须发现并报告系统中设备的到达和离开情况。 总线驱动程序标识和报告的设备称为总线的 子设备。 标识和报告子设备的过程称为 总线枚举。 在总线枚举期间,总线驱动程序会为其子 设备创建设备对象 。  总线驱动程序本质上是同时处理总线枚