zoukankan      html  css  js  c++  java
  • linux 本地套接字通信

    本地套接字通信

    利用本地套接字,也可以进程间通信。

    本地套接字和有名管道一样都利用伪文件

    管道的文件类型是p

    本地套接字的文件类型是s。

    当调用bind函数后,就会生成本地套接字对应的伪装文件

    srwxr-xr-x 1 ys ys     0 7月   2 10:55 server.socket
    srwxr-xr-x 1 ys ys     0 7月   2 10:55 client.socket
    

    和网络套接字不同的地方是:

    • 使用的结构体不一样,本地套接字使用:
    struct sockaddr_un{
        sun_family;//AF_LOCAL
        sun_path;//本地套接字对应的伪装文件的名字,可以加路径
    }
    
    • 客户都也必须调用bind函数
    • 需要头文件:sys/un.h
    • 需要提前删除上次执行生成的伪装文件,如果不删除的话,bind函数会执行失败,错误信息:Address already in use

    接收端例子:

    #include <sys/types.h>         
    #include <sys/socket.h>
    #include <sys/un.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    int main(){
      int fd = socket(AF_LOCAL, SOCK_STREAM, 0);
      
      unlink("server.socket");
      
      struct sockaddr_un serv;
      strcpy(serv.sun_path, "server.socket");
      serv.sun_family = AF_LOCAL;
      int ret = bind(fd, (struct sockaddr*)&serv, sizeof(serv));
      if(ret == -1){
        perror("bind error");
        exit(1);
      }
    
      listen(fd, 64);
    
      struct sockaddr_un cli;
      socklen_t len;
      int cfd = accept(fd, (struct sockaddr*)&cli, &len);
    
      while(1){
        char buf[64];
        ret = recv(cfd, buf, sizeof(buf), 0);
        if(ret == -1){
          perror("recv error");
          exit(1);
        }
        else if(ret == 0){
          printf("client closed
    ");
          close(cfd);
        }
        printf("clinet path:%s
    ", cli.sun_path);
        write(STDOUT_FILENO, buf, ret);
      }
    
      close(cfd);
      close(fd);
    }
    
    

    发送端例子:

    #include <sys/types.h>         
    #include <sys/socket.h>
    #include <sys/un.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
    
    int main(){
      int fd = socket(AF_LOCAL, SOCK_STREAM, 0);
    
      unlink("client.socket");
      
      struct sockaddr_un cli;
      strcpy(cli.sun_path, "client.socket");
      cli.sun_family = AF_LOCAL;
      if(bind(fd, (struct sockaddr*)&cli, sizeof(cli)) == -1){
        perror("bind cli error");
        exit(1);
      }
      
    
      struct sockaddr_un to;
      to.sun_family = AF_LOCAL;
      strcpy(to.sun_path, "server.socket");
    
      int ret = connect(fd, (struct sockaddr*)&to, sizeof(to));
    
      int cnt = 0;
      while(1){
        char buf[64] = {0};
        sprintf(buf, "cnt = %d", cnt++);
        int ret = send(fd, buf, sizeof(buf), 0);
        if(ret == -1){
          perror("send error");
          exit(1);
        }
        sleep(1);
      }
    }
    
    

    c/c++ 学习互助QQ群:877684253

    本人微信:xiaoshitou5854

  • 相关阅读:
    Git一些简单但非常重要并常用的操作命令
    利用fastjson解析json并通过js&ajax实现页面的无跳转刷新
    利用Graphviz绘制逻辑关系依赖图
    oracle导入.dmp文件
    Linux查找当前目录5天的文件并打包
    Web安全相关(三):开放重定向(Open Redirection)
    Web安全相关(二):跨站请求伪造(CSRF/XSRF)
    Web安全相关(一):跨站脚本攻击(XSS)
    密码学应用(DES,AES, MD5, SHA1, RSA, Salt, Pkcs8)
    行为驱动开发(BDD)实践示例
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/11119455.html
Copyright © 2011-2022 走看看