加入收藏 | 设为首页 | 会员中心 | 我要投稿 我爱制作网_池州站长网 (https://www.0566zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Unix > 正文

socket进程间通信方式大总结,还有典型实例哦

发布时间:2022-12-14 10:53:23 所属栏目:Unix 来源:
导读:  socket在主机间和进程间使用,方法类似,主要区别是进程间通信使用的是sockaddr_un,而主机间的通信使用的是sockadd_in。

  每个套接字都有其自己的地址格式unix进程通信,对于AF_UNIX域套接字来说,它的地
  socket在主机间和进程间使用,方法类似,主要区别是进程间通信使用的是sockaddr_un,而主机间的通信使用的是sockadd_in。
 
  每个套接字都有其自己的地址格式unix进程通信,对于AF_UNIX域套接字来说,它的地址由结构sockaddr_un来描述,该结构定义在头文件sys/un.h中,它的定义如下:
 
  struct sockaddr_un {
 
  __kernel_sa_family_t sun_family; /* AF_UNIX */
 
  char sun_path[UNIX_PATH_MAX]; /* pathname */
 
  };
 
  对于AF_INET域套接字来说,它的地址结构由sockaddr_in来描述,它至少包括以下几个成员:
 
  struct sockaddr_in {
 
  __kernel_sa_family_t sin_family; /* Address family */
 
  __be16 sin_port; /* Port number */
 
  struct in_addr sin_addr; /* Internet address */
 
  /* Pad to size of `struct sockaddr'. */
 
  unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) -
 
  sizeof(unsigned short int) - sizeof(struct in_addr)];
 
  };
 
  使用socket作为进程间通信方式,有什么注意事项?
 
  (1) Server
 
  a. 创建一个server socket
 
  创建的socket是AF_UNIX域的。
 
  b. 设置Server的地址
 
  利用bind函数。
 
  注意:地址一般通过一个字符串来标识,一般的做法是通过一个Linux路径来实现;注意使用之前必须要把该路径unlink掉,否则可能出现bind失败的情况。
 
  c. 开始监听
 
  利用listen函数。
 
  注意:最大监听的长度为128.
 
  d. 接收连接
 
  利用accept函数。
 
  注意:accept函数默认为阻塞模式。有一个可以设置非阻塞的为accept4函数;
 
  在accept函数阻塞的过程中,一些信号对打断accept的阻塞,这是正常现象。因此如果要设置一直阻塞,需要考虑这种情况。
 
  e. 接收数据
 
  利用recv()函数
 
  注意:recv函数是在accept新生成的socket上接收消息。recv()函数可以工作在阻塞模式,也可以工作在非阻塞模式。一般都是阻塞模式。新生成的socket注意要关闭。
 
  (2) client
 
  a. 创建
 
  注意域为AF_UNIX。
 
  b. 连接服务器:connect调用
 
  注意:connect为非阻塞模式,需要增加重试机制保证可靠性。
 
  c. 发送数据:send
 
  注意:该调用可以是阻塞的,也可以是非阻塞的,最好设置为非阻塞模式,默认为阻塞模式。另外,可以调用setsockopt()来设置阻塞时长。level:SOL_SOCKET,SO_SNDTIMEO。
 
  例子如下:
 
  server
 
  #include
 
  #include
 
  #include
 
  #include
 
  #include
 
  #include
 
  #include
 
  #include
 
  #include
 
  typedef struct sockaddr SA;
 
  int main(int argc, const char *argv[])
 
  {
 
  //1.定义变量
 
  int sockfd, clientfd;
 
  socklen_t addrlen = sizeof(SA);
 
  struct sockaddr_un addr;
 
  ssize_t nbytes;
 
  char buf[32] = {0};
 
  //2.创建本地套接字接口
 
  sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
 
  if(sockfd < 0){
 
  perror("socket err");
 
  exit(-1);
 
  }
 
  //3.填充本地地址信息
 
  bzero(&addr, addrlen);
 
  addr.sun_family = AF_UNIX;
 
  strcpy(addr.sun_path, "unix_sock");
 
  //4.绑定本地套接字
 
  remove("unix_sock");
 
  if(bind(sockfd, (struct sockaddr *)&addr, addrlen) < 0){
 
  perror("bind err");
 
  exit(-1);
 
  }
 
  //5.监听套接字
 
  if(listen(sockfd, 5) < 0){
 
  perror("listen err");
 
  exit(-1);
 
  }
 
  //6.接收连接
 
  clientfd = accept(sockfd, NULL, NULL);
 
  while(1)
 
  {
 
  //7.接收客户端数据
 
  nbytes = recv(clientfd, buf, 32, 0);
 
  if(nbytes < 0){
 
  perror("recv err");
 
  exit(-1);
 
  }else if (nbytes == 0) {
 
  printf("peer exit\n");
 
  break;
 
  }else{
 
  printf("recv data = %s\n", buf);
 
  }
 
  }
 
  //8.关闭套接字
 
  close(clientfd);
 
  close(sockfd);
 
  }
 
  client
 
  #include
 
  #include
 
  #include
 
  #include
 
  #include
 
  #include
 
  #include
 
  #include
 
  #include
 
  typedef struct sockaddr SA;
 
  int main(int argc, const char *argv[])
 
  {
 
  //1.定义变量
 
  int sockfd;
 
  socklen_t addrlen = sizeof(SA);
 
  struct sockaddr_un addr;
 
  char buf[32] = {0};
 
  //2.创建本地套接字接口
 
  sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
 
  if(sockfd < 0){
 
  perror("socket err");
 
  exit(-1);
 
  }
 
  //3.填充服务器的地址信息
 
  bzero(&addr, addrlen);
 
  addr.sun_family = AF_UNIX;
 
  strcpy(addr.sun_path, "unix_sock");
 
  //4.连接服务器
 
  if(connect(sockfd, (struct sockaddr *)&addr, addrlen) < 0){
 
  perror("connect err");
 
  exit(-1);
 
  }
 
  //5.收发数据
 
  while (1) {
 
  gets(buf);
 
  send(sockfd, buf, 32, 0);
 
  }
 
  //6.关闭套接字
 
  close(sockfd);
 
  }
 

(编辑:我爱制作网_池州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章