zoukankan      html  css  js  c++  java
  • IPC-本地套接字

    一。Unix domain socket概念

      socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC更有效率:不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。这是因为,IPC机制本质上是可靠的通讯,而网络协议是为不可靠的通讯设计的。

      UNIX Domain Socket是全双工的,API接口语义丰富,相比其它IPC机制有明显的优越性,目前已成为使用最广泛的IPC机制,比如X Window服务器和GUI程序之间就是通过UNIXDomain Socket通讯的。

    二。本地套接字地址结构

    struct sockaddr_un {

    __kernel_sa_family_t sun_family;                  /* AF_UNIX */                  地址结构类型

    char sun_path[UNIX_PATH_MAX];                 /* pathname */                socket文件名(含路径)

    };

    三。代码示例

    服务端

     1 #include <stdio.h>
     2 #include <unistd.h>
     3 #include <sys/socket.h>
     4 #include <strings.h>
     5 #include <string.h>
     6 #include <ctype.h>
     7 #include <arpa/inet.h>
     8 #include <sys/un.h>
     9 #include <stddef.h>
    10 
    11 #include "wrap.h"
    12 
    13 #define SERV_ADDR  "serv.socket"
    14 
    15 int main(void)
    16 {
    17     int lfd, cfd, len, size, i;
    18     struct sockaddr_un servaddr, cliaddr;
    19     char buf[4096];
    20 
    21     lfd = socket(AF_UNIX, SOCK_STREAM, 0);    //本地套接字 AF_UNIX
    22 
    23     bzero(&servaddr, sizeof(servaddr));
    24     servaddr.sun_family = AF_UNIX;         //初始化地址信息  
    25     strcpy(servaddr.sun_path,SERV_ADDR);    //套接字文件名
    26 
    27     len = offsetof(struct sockaddr_un, sun_path) + strlen(servaddr.sun_path);     /* servaddr total len */
    28     //offsetof计算结构体中成员的偏移量,偏移量+文件名大小=结构体长度
    29 
    30 
    31     unlink(SERV_ADDR);                              /* 确保bind之前serv.sock文件不存在,bind会创建该文件 */
    32     bind(lfd, (struct sockaddr *)&servaddr, len);           /* 参3不能是sizeof(servaddr) */
    33 
    34     listen(lfd, 20);
    35 
    36     printf("Accept ...
    ");
    37     while (1) {
    38         len = sizeof(cliaddr);
    39         cfd = accept(lfd, (struct sockaddr *)&cliaddr, (socklen_t *)&len);
    40 
    41         len -= offsetof(struct sockaddr_un, sun_path);      /* 得到文件名的长度 */
    42         cliaddr.sun_path[len] = '';                       /* 确保打印时,没有乱码出现 */
    43 
    44         printf("client bind filename %s
    ", cliaddr.sun_path);
    45 
    46         while ((size = read(cfd, buf, sizeof(buf))) > 0) {
    47             for (i = 0; i < size; i++)
    48                 buf[i] = toupper(buf[i]);
    49             write(cfd, buf, size);
    50         }
    51         close(cfd);
    52     }
    53     close(lfd);
    54 
    55     return 0;
    56 }

    客户端

    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>         
    #include <sys/socket.h>
    #include <strings.h>
    #include <string.h>
    #include <ctype.h>
    #include <arpa/inet.h>
    #include <sys/un.h>
    #include <stddef.h>
    
    #include "wrap.h"
    
    #define SERV_ADDR "serv.socket"
    #define CLIE_ADDR "clie.socket"
    
    int main(void)
    {
        int  cfd, len;
        struct sockaddr_un servaddr, cliaddr;
        char buf[4096];
    
        cfd = socket(AF_UNIX, SOCK_STREAM, 0);
    
        bzero(&cliaddr, sizeof(cliaddr));
        cliaddr.sun_family = AF_UNIX;
        strcpy(cliaddr.sun_path,CLIE_ADDR);
    
        len = offsetof(struct sockaddr_un, sun_path) + strlen(cliaddr.sun_path); /*计算客户端地址结构有效长度 */
    
        unlink(CLIE_ADDR);
        bind(cfd, (struct sockaddr *)&cliaddr, len);                                 /* 客户端也需要bind, 不能依赖自动绑定*/
    
        
        bzero(&servaddr, sizeof(servaddr));                                          /* 构造server 地址 */
        servaddr.sun_family = AF_UNIX;
        strcpy(servaddr.sun_path,SERV_ADDR);
    
        len = offsetof(struct sockaddr_un, sun_path) + strlen(servaddr.sun_path);   /* 计算服务器端地址结构有效长度 */
    
        connect(cfd, (struct sockaddr *)&servaddr, len);
    
        while (fgets(buf, sizeof(buf), stdin) != NULL) {
            write(cfd, buf, strlen(buf));
            len = read(cfd, buf, sizeof(buf));
            write(STDOUT_FILENO, buf, len);
        }
    
        close(cfd);
    
        return 0;
    }
  • 相关阅读:
    搭建公共DNS服务器[转]
    zabbix3.4 yum快速安装
    centos7安装图形化界面并远程连接
    记一次排查黑客入侵
    centos6安装图形界面并远程连接
    树莓派做NAS
    document.documentElement.scrollTop||document.body.scrollTop;
    矩阵连乘
    母函数详解
    Catalan 数
  • 原文地址:https://www.cnblogs.com/sclu/p/11315210.html
Copyright © 2011-2022 走看看