zoukankan      html  css  js  c++  java
  • linux 系统下使用socket进行本地进程间通信

    转自:https://blog.csdn.net/baidu_24553027/article/details/54912724

    使用套接字除了可以实现网络间不同主机间的通信外,还可以实现同一主机的不同进程间的通信,且建立的通信是双向的通信。socket进程通信与网络通信使用的是统一套接口,只是地址结构与某些参数不同。

    其主要流程如下:

     

    代码实现如下:

    客户端:

    1.  
      //client
    2.  
      #include<stdio.h>
    3.  
      #include<string.h>
    4.  
      #include<sys/types.h>
    5.  
      #include<sys/socket.h>
    6.  
      #include<sys/un.h>
    7.  
      #define UNIX_DOMAIN "/home/zhangmiaoling/test/socket/UNIX.domain"
    8.  
      int main(){
    9.  
      int connect_fd;
    10.  
      int ret;
    11.  
      char send_buff[1024];
    12.  
      int i;
    13.  
      static struct sockaddr_un srv_addr;
    14.  
      // creat unix socket
    15.  
      connect_fd=socket(PF_UNIX,SOCK_STREAM,0);
    16.  
      if(connect_fd<0){
    17.  
      perror("cannot creat socket");
    18.  
      return -1;
    19.  
      }
    20.  
      srv_addr.sun_family=AF_UNIX;
    21.  
      strcpy(srv_addr.sun_path,UNIX_DOMAIN);
    22.  
      //connect server
    23.  
      ret=connect(connect_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr));
    24.  
      if (ret<0){
    25.  
      perror("cannot connect server");
    26.  
      close(connect_fd);
    27.  
      return -1;
    28.  
      }
    29.  
      memset(send_buff,0,1024);
    30.  
      strcpy(send_buff,"message from client");
    31.  
      //send info server
    32.  
      write(connect_fd,send_buff,sizeof(send_buff));
    33.  
      close(connect_fd);
    34.  
      return 0;
    35.  
      }

    服务器端:
    1.  
      //server
    2.  
      #include<stdio.h>
    3.  
      #include<sys/socket.h>
    4.  
      #include<sys/types.h>
    5.  
      #include<sys/un.h>
    6.  
      #define UNIX_DOMAIN "/home/zhangmiaoling/test/socket/UNIX.domain"
    7.  
       
    8.  
      int main(){
    9.  
       
    10.  
      socklen_t clt_addr_len;
    11.  
      int listen_fd;
    12.  
      int com_fd;
    13.  
      int ret;
    14.  
      int i;
    15.  
      static char rcv_buff[1024];
    16.  
      int len;
    17.  
      struct sockaddr_un clt_addr;
    18.  
      struct sockaddr_un srv_addr;
    19.  
      listen_fd=socket(AF_UNIX,SOCK_STREAM,0);
    20.  
      if(listen_fd<0){
    21.  
      perror("connect creat communication socket");
    22.  
      }
    23.  
      // set srv_addr param
    24.  
      srv_addr.sun_family=AF_UNIX;
    25.  
      strncpy(srv_addr.sun_path,UNIX_DOMAIN,sizeof(srv_addr.sun_path)-1);
    26.  
      unlink(UNIX_DOMAIN);
    27.  
      //bind sockfd&addr
    28.  
      ret=bind(listen_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr));
    29.  
      if(ret<0){
    30.  
      perror("cannot bind server socket");
    31.  
      close(listen_fd);
    32.  
      unlink(UNIX_DOMAIN);
    33.  
      return -1;
    34.  
      }
    35.  
      //listen sockfd
    36.  
      ret=listen(listen_fd,1);
    37.  
      if(ret<0){
    38.  
      perror("cannot listen sockfd");
    39.  
      close(listen_fd);
    40.  
      unlink(UNIX_DOMAIN);
    41.  
      return -1;
    42.  
      }
    43.  
      //have connect requst use accept
    44.  
      len=sizeof(clt_addr);
    45.  
      com_fd=accept(listen_fd,(struct sockaddr*)&clt_addr,&len);
    46.  
      if(com_fd<0){
    47.  
      perror("cannot accept requst");
    48.  
      close(listen_fd);
    49.  
      unlink(UNIX_DOMAIN);
    50.  
      return -1;
    51.  
      }
    52.  
      //read and printf client send info
    53.  
      printf(" ******info******** ");
    54.  
      //for(i=0,i<4,i++){
    55.  
      for(i=0;i<4;i++){
    56.  
      memset(rcv_buff,0,1024);
    57.  
      int num = read(com_fd,rcv_buff,sizeof(rcv_buff));
    58.  
      printf("message from client %d : %s ",num,rcv_buff);
    59.  
      }
    60.  
      close(com_fd);
    61.  
      close(listen_fd);
    62.  
      unlink(UNIX_DOMAIN);
    63.  
      return 0;
    64.  
       
    65.  
      }

    一. 创建socket

       创建socket,类型为AF_LOCAL或AF_UNIX,表示用于进程通信:

    调用函数socket(),其原型如下:

    int socket(int domain, int type, int protocol);

    参数:

    domain:指定协议族,对于本地套接字来说,值必须设置为AF_UNIX枚举值;

    type:指定套接字类型,可以被设置为SOCK_STREAM(流式套接字)活SOCK_DGRAM(数据报式套接字)

    protocol:指定具体的协议,应被设置为0

    返回值为生成的套接字描述符。

    对于本地套接字来说,流式套接字(SOCK_STREAM)是一个有顺序的、可靠的双向字节流,相当于在本地进程之间建立起一条数据通道;数据报式套接字(SOCK_DGRAM)相当于单纯的发送消息,在进程通信过程中,理论上可能会有信息丢失、复制或者不按先后次序到达的情况,但由于其在本地通信,不通过外界网络,这些情况出现的概率很小。

    二. 设置socket参数

       SOCK_STREAM式本地套接字的通信双方均需要有本地地址,其中服务器端的本地地址需要明确指定,指定方法是使用struct sockaddr_un类型的变量

    struct sockaddr_un{

      sa_family_t    sun_family;        // AF_UNIX

      char    sun_path[UNIX_PATH_MAX];  // 路径名

    }

    三. 绑定

        绑定要使用 bind 系统调用,其原形如下:    

    int bind(int socket, const struct sockaddr *address, size_t address_len);

    参数

    socket:服务端套接字描述符

    address:需要绑定的服务端本地地址

    address_len:本地地址的字节长度

    四. 监听

        服务器端套接字创建完毕并赋予本地地址值(名称,本例中为CAN_SERVICE)后,需要进行监听,等待客户端连接并处理请求,监听使用 listen 系统调用,接受客户端连接使用accept系统调用,它们的原形如下:
    int listen(int socket, int backlog);
    int accept(int socket, struct sockaddr *address, size_t *address_len);
    参数

    socket:表示服务器端的套接字描述符;

    backlog 表示排队连接队列的长度(若有多个客户端同时连接,则需要进行排队);

    address 表示当前连接客户端的本地地址,该参数为输出参数,是客户端传递过来的关于自身的信息;

    address_len 表示当前连接客户端本地地址的字节长度,这个参数既是输入参数,又是输出参数。实现监听、接受和处理。

    五. 连接

        客户端需要socket系统调用connect()连接到服务端,其函数原型如下:

    int connect(int socket, const struct sockaddr *address, size_t address_len);
    参数

    socket:客户端的套接字描述符

    address:当前客户端的本地地址,是一个 struct sockaddr_un 类型的变量

    address_len:表示本地地址的字节长度

    五. 数据交互

        无论客户端还是服务器,都要和对方进行数据上的交互。一个进程扮演客户端的角色,另外一个进程扮演服务器的角色,两个进程之间相互发送接收数据,这就是基于本地套接字的进程通信。

        循环读取客户端发送的消息,当客户端没有发送数据时会阻塞直到有数据到来。如果想要多个连接并发处理,需要创建线程,将每个连接交给相应的线程并发处理。接收到数据后,进行相应的处理,将结果返回给客户端。发送和接收数据要使用 write 和 read 系统调用,它们的原形为:
    int read(int socket, char *buffer, size_t len);
    int write(int socket, char *buffer, size_t len);

  • 相关阅读:
    计算与软件工程作业一
    《CLSZS团队》:团队项目选题报告
    计算与软件工程第五次作业
    计算与软件工程第四次作业
    计算与软件工程代码规范
    计算与软件工程第三次作业
    计算与软件工程第二次作业
    壹贰叁肆团队项目选题报告
    计算与软件工程 作业五
    计算与软件工程 作业四
  • 原文地址:https://www.cnblogs.com/x_wukong/p/9554010.html
Copyright © 2011-2022 走看看