首页 > 其他分享 >Unix 域协议

Unix 域协议

时间:2023-08-05 22:12:30浏览次数:25  
标签:协议 int server Unix client address sockfd 接字

Unix 域协议

unix域协议是在单个主机上执行客户端/服务器通信的一种方法,使用套接字API,可使用IPC的方法一种。

分为两类:字节流套接字(类似TCP)、数据报套接字(类似UDP)

  1. Unix域套接字比位于同一个主机的TCP套接字快,X Window System 就使用了Unix域协议
  2. 在不同进程间传递描述符
  3. 能把客户的凭证(用户ID和组ID)提供给服务器,从而提供额外的安全检查措施
  4. 使用普通文件系统的路径名作为标识,而非ip和端口。这些特殊文件除非和Unix域套接字关联,否则无法读写
// unix域套接字地址,可使用 bind getsockname 等函数操作
struct sockaddr_un {
  sa_family_t sun_family; /* AF_UNIX */
  char sun_path[108];     /* Path name. 为空时等价于 INADDR_ANY */
};

// Returns 0 on success, -1 for errors.
int socketpair(
    int __domain,    // AF_LOCAL
    int __type,      // SOCK_STREAM or SOCK_DGRAM
    int __protocol,  // 0
    int __fds[2]);   // 返回两个新创建的文件描述符,类似 pipe
                    // 但是此处的两个文件描述符都是全双工的,可以双向通信
  1. 应当捆绑绝对路径
  2. connect 指定的绝对路径应绑定某个打开的Unix域套接字,且套接字类型一致
  3. 调用 connect 连接的权限类似以只读权限 open 路径
  4. Unix域套接字的connect调用发现监听套接字的队列满后,调用立即返回一个 ECONNREFUSED 错误;TCP此时会忽略新到达的SYN,发起端将重试SYN
  5. 与TCP UDP会分配临时端口不同,给未绑定的套接字发信息不会自动绑定路径名
流式服务端
 #include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>

const char *UNIXSTR_PATH = "/tmp/unix_domain_socket";

int main(int argc, char const *argv[]) {
  int server_sockfd, client_sockfd;
  socklen_t client_len;
  struct sockaddr_un server_address;
  struct sockaddr_un client_address;

  // 删除并创建新套接字
  if (unlink(UNIXSTR_PATH) < 0) {
    perror("unlink");
  }
  server_sockfd = socket(AF_UNIX,  // 等于AF_LOCAL
                         SOCK_STREAM, 0);

  // 命名套接字
  server_address.sun_family = AF_UNIX;
  strcpy(server_address.sun_path, UNIXSTR_PATH);
  // 创建文件权限为 0777 按umask修正后的值
  if (bind(server_sockfd, (struct sockaddr *)&server_address,
           sizeof(server_address)) < 0) {
    perror("bind");
    return -1;
  }

  // 建立连接队列
  listen(server_sockfd, 5);
  while (1) {
    char ch;
    printf("server waiting\n");

    // 接受一个连接
    client_len = sizeof(client_address);
    client_sockfd =
        accept(server_sockfd, (struct sockaddr *)&client_address, &client_len);

    // 操作 socket
    read(client_sockfd, &ch, 1);
    printf("client_sockfd = %d send: %c \n", client_sockfd, ch);
    ch++;
    write(client_sockfd, &ch, 1);
    close(client_sockfd);
  }
  return 0;
}
流式客户端
 #include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>

const char* UNIXSTR_PATH = "/tmp/unix_domain_socket";

int main(int argc, char const *argv[]) {
  int ret{0};
  int client_sockfd;
  struct sockaddr_un server_address;

  client_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

  bzero(&server_address, sizeof(server_address));
  server_address.sun_family = AF_UNIX;
  strncpy(server_address.sun_path, UNIXSTR_PATH,
          sizeof(server_address.sun_path) - 1);

  ret = connect(client_sockfd, (struct sockaddr *)&server_address,
                sizeof(server_address));
  if (ret < 0) {
    perror("connect");
    return -1;
  }

  char ch{'a'};
  write(client_sockfd, &ch, 1);
  read(client_sockfd, &ch, 1);
  printf("char from server = %c\n", ch);

  close(client_sockfd);
  return 0;
}

数据报类型协议与UDP类似,但是必须显示bind一个路径名到套接字

描述符传递

父子进程可通过fork或exec命令传递描述符,而通过Unix域套接字使用 sendmsg 发送特殊消息,可以在任意进程间传递描述符

建立流式域套接字(数据报域套接字可能丢失数据,就像UDP),可以传输任意类型的描述符。发送进程构建一个 msfhdr 结构,其中 msfhdr 的 msg_control 成员用于发送描述符
调用sendmsg发送后,即使在对方接收前关闭了该描述符,此进程仍保持打开状态,发送描述符会使其引用计数加1
接收的描述符可能具有不同的描述符号,这是正常的,传输过程涉及在接收进程中创建一个新的描述符,新旧描述符指向内核中同一个文件表项

标签:协议,int,server,Unix,client,address,sockfd,接字
From: https://www.cnblogs.com/zhh567/p/17608726.html

相关文章

  • 《UNIX 传奇:历史与回忆》读后感
    《UNIX传奇:历史与回忆》是bwk(BrianW.Kernighan)2019年的新作,回忆了UNIX在大半个世纪的风雨历程,是一本引人入胜的书籍。通过对UNIX操作系统的历史和发展进行详细的叙述和回顾,让我对这个操作系统有了更深入的了解。读完这本书,我不仅对UNIX的技术细节有了更清晰的认识,也对......
  • ICMP协议的作用,Ping of Death攻击的原理是什么?
    ICMP是“InternetControlMessageProtocol”(Internet控制消息协议)的缩写。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传......
  • Http协议
    HTTP协议什么是HTTP协议?什么是协议?协议是指双方,或多方,相互约定好,大家都需要遵守的规则,叫协议。所谓HTTP协议,就是指,客户端和服务器之间通信时,发送的数据,需要遵守的规则,叫HTTP协议。HTTP协议中的数据又叫报文。请求的HTTP协议格式客户端给服务器发送数据叫请求。服......
  • CT485modbus协议RS485接口开启合口式电流互感器传感器变送器
    www.daq-iot.com 19936624857—————————————————————————— SC-GP-CT485开口式电流互感器是上海数采物联网科技有限公司推出的一款可以把交流电模拟信号转换成485数字信号的一种电流传感器(互感器),产品内置32位ARM系列MCU和高精度计量芯片,经多点校......
  • 三菱 网络模块 MC协议 通信配置
    三菱 plc mc 协议 QJ71E71-100  百度一下 三菱mc协议配置,再参考一下  ......
  • PROFINET转ETHERCAT协议网关ethercat和profinet的伺服区别
    捷米特JM–ECAT-PN是自主研发的一款PROFINET从站功能的通讯网关。该产品主要功能是将PROFINET网络和ETHERCAT网络连接起来。捷米特JM-ECAT-PN连接到PROFINET总线中做为从站使用,连接到ETHERCAT总线中做为从站使用。3.技术参数PROFINET技术参数网关做为PROFINET网......
  • SL651协议解析网关有什么功能?有什么应用场景?
    协议解析网关是工业物联网和自动化控制领域常见的设备,是数据采集通信系统的基础。PLC、仪器仪表、数控机床、工业机器人、水电表、传感器等设备有不同的通信协议,协议解析网关就是可以接入设备进行协议解析,从而采集设备数据并进行标准化处理,方便对接到云平台和上位机中。物通博联提......
  • 视频融合平台视频汇聚平台LiteCVR接入协议通道播放失败反馈处理案例
    我们近期正在整理以前到近期的用户反馈,今后将陆续把已经整理好的案列以图文的形式分享给大家参考。有用户反馈称,在他们现场部署了LiteCVR平台后,NVR设备通过国标GB28181协议成功接入到LiteCVR。尽管设备和通道都显示为在线状态,但是他们发现部分通道的视频无法正常播放。因此,他们请求......
  • 工程监测仪器多通道振弦数据记录仪的MODBUS通讯协议
    工程监测仪器多通道振弦数据记录仪的MODBUS通讯协议解析多通道振弦数据记录仪是多通道振弦、温度信号采集记录仪,具备32通道传感器接口,可对最多16通道振弦频率和16通道温度、32通道振弦频率进行实时或全自动定时采集记录(支持内部存储并可外接U盘);RS232和RS485数据接......
  • 十五、基于MQTT协议上传属性至ONENET Studio
    1.准备工作(1)下载MQTT透传固件(安心可官网下载即可)(2)下载MQTT固件到ESP82662.AT指令连接设备上传属性值(1)AT\r\n(2)AT+RST\r\n(3)AT+CWMODE=1\r\n(4)AT+CWDHCP=1,1\r\n(5)AT+CWJAP="WIFISSID","密码"\r\n//连接路由器(6)AT+MQTTUSERCFG=0,1,"设备名/设备id","产品I......