利用套接字实现进程通信一例

下面程序实现的功能是:客户端将从键盘输入的内容发送给服务器,然后服务器在将受到的数据原封不动的发给客户端。

先看看服务器端的程序:

   1:  /*
   2:   * =====================================================================================
   3:   *
   4:   *       Filename:  server.c
   5:   *
   6:   *    Description:  tcp
   7:   *
   8:   *        Version:  1.0
   9:   *        Created:  03/11/2013 02:34:43 PM
  10:   *       Revision:  none
  11:   *       Compiler:  gcc
  12:   *
  13:   *         Author:  YOUR NAME (), 
  14:   *        Company:  
  15:   *
  16:   * =====================================================================================
  17:   */
  18:   
  19:  #include <stdio.h>
  20:  #include <sys/socket.h>
  21:  #include <netinet/in.h>
  22:  #include <arpa/inet.h>
  23:  #include <string.h>
  24:  #include <stdlib.h>
  25:  #include <unistd.h>
  26:   
  27:  typedef struct sockaddr SA;  //
  28:  #define N 128
  29:   
  30:  int main(int argc, char *argv[])
  31:  {
  32:      int listenfd, confd;  //定义listend用于存放监听套接字的描述符,confd用于存放accept返回的已建立连接套接字的描述符。
  33:      struct sockaddr_in my_addr, peer_addr;//my_addr用于存放监听套接字要绑定的信息,peer_addr存放客户端套接字的信息
  34:      socklen_t peer_len = sizeof(my_addr);  //peer_len最好定义时初始化,且必须初始化!
  35:      char buffer[N]; //
  36:      int n;
  37:   
  38:      if(argc < 3)  //参数检查
  39:      {
  40:          printf("input error! %s <ip> <port>\n",argv[0]);
  41:          exit(-1);
  42:      }
  43:   
  44:      if((listenfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)  //创建套接字,用于TCP连接
  45:      {
  46:          perror("socket error!");
  47:          exit(-1);
  48:      }
  49:      
  50:     bzero(&my_addr, sizeof(my_addr));  //先将my_addr清空
  51:   
  52:     //初始化监听套接字的绑定信息
  53:     my_addr.sin_family = PF_INET;     //网络协议 
  54:     
  55:     /*
  56:        ./client 192.168.1.173 8888
  57:        argv[2]中是字符串“8888”的首地址,atoi将字符串“8888”,转化成数字8888,
  58:        因为端口号是需要发送的,所以需要转换成网络字节序,通过htons实现
  59:     */
  60:     my_addr.sin_port = htons(atoi(argv[2]));  
  61:     
  62:     my_addr.sin_addr.s_addr = inet_addr(argv[1]);//将字符串"192.168.1.173"转成32位的无符号整型
  63:   
  64:     if(bind(listenfd, (SA *)&my_addr, sizeof(my_addr)) < 0)  //将监听套接字进行绑定
  65:     {
  66:         perror("error bind");
  67:         exit(-1);
  68:     }
  69:   
  70:     if(listen(listenfd, 5) < 0)  //将监听套接字设置为监听模式,等待请求队列长度为5
  71:     {
  72:   
  73:         perror("listen error!");
  74:         exit(-1);
  75:     }
  76:   
  77:     while(1)
  78:     {
  79:     /*
  80:           当没有客户端请求时,服务器在此阻塞。直到有客户端请求,然后返回一个新的套接字描述符confd,与
  81:           listenfd是相同类型的,但是confd可以用于与客户端收发数据,而listenfd不行,它只能监听。
  82:           注意:accept返回的是一个新的已经与客户端建立连接的套接字confd,他有两个缓冲区,输入和输出,
  83:           只有他才可以与客户端进行通信。他的类型与监听套接字一样。
  84:     */
  85:         if((confd = accept(listenfd, (SA *)&peer_addr, &peer_len)) < 0)  
  86:         {
  87:             perror("accpt error!");
  88:             exit(-1);
  89:         }
  90:   
  91:         printf("client : [%s:%d]\n",inet_ntoa(peer_addr.sin_addr), ntohs(peer_addr.sin_port));
  92:         
  93:         while(recv(confd, buffer, N,0) > 0)  //将套接字confd的接收缓冲区的数据拷贝到buffer,当客户端关闭连接时,返回0。
  94:         {
  95:             printf("I have get > %s",buffer);
  96:             if(send(confd, buffer, N, 0) == -1)   //将buffer中的数据拷贝到confd的发送缓冲区
  97:             {
  98:                 perror("fail to send");
  99:                 exit(-1);
 100:             }
 101:         }
 102:   
 103:         printf("client : [%s:%d] have closed!\n",inet_ntoa(peer_addr.sin_addr), ntohs(peer_addr.sin_port));
 104:         close(confd);
 105:     }
 106:   
 107:      return 0;
 108:  }

客户端:

   1:  /*
   2:   * =====================================================================================
   3:   *
   4:   *       Filename:  server.c
   5:   *
   6:   *    Description:  tcp
   7:   *
   8:   *        Version:  1.0
   9:   *        Created:  03/11/2013 02:34:43 PM
  10:   *       Revision:  none
  11:   *       Compiler:  gcc
  12:   *
  13:   *         Author:  YOUR NAME (), 
  14:   *        Company:  
  15:   *
  16:   * =====================================================================================
  17:   */
  18:   
  19:  #include <stdio.h>
  20:  #include <sys/socket.h>
  21:  #include <sys/types.h>
  22:  #include <netinet/in.h>
  23:  #include <arpa/inet.h>
  24:  #include <string.h>
  25:  #include <stdlib.h>
  26:  #include <unistd.h>
  27:   
  28:   
  29:  #define N 128
  30:   
  31:  typedef struct sockaddr SA;
  32:   
  33:  int main(int argc, char *argv[])
  34:  {
  35:      int sockfd;  //客户端套接字,客户端只需一个,且不需要绑定
  36:      struct sockaddr_in server_addr;  //服务器的ip端口信息
  37:      char buffer[N];
  38:   
  39:      if(argc < 3)
  40:      {
  41:          printf("usage! %s <ip> <port>\n",argv[0]);
  42:          exit(-1);
  43:      }
  44:   
  45:      if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)   //创建客户端套接字
  46:      {
  47:          perror("socket error!");
  48:          exit(-1);
  49:      }
  50:      
  51:     bzero(&server_addr, sizeof(server_addr)); 
  52:   
  53:     /*
  54:     初始化要连接的服务器信息
  55:     */
  56:     server_addr.sin_family = PF_INET;
  57:     server_addr.sin_port = htons(atoi(argv[2]));
  58:     server_addr.sin_addr.s_addr = inet_addr(argv[1]);
  59:   
  60:     if(connect(sockfd, (SA *)&server_addr, sizeof(server_addr)) < 0)  //连接服务器
  61:     {
  62:         perror("fail to connect");
  63:         exit(-1);
  64:     }
  65:   
  66:     printf("> ");
  67:     while(fgets(buffer, N, stdin) != 0)
  68:     {
  69:         if(send(sockfd, buffer, N, 0) == -1)
  70:         {
  71:             perror("fail to send");
  72:             exit(-1);
  73:         }
  74:          if(strncmp(buffer, "quit", 4) == 0)
  75:          {
  76:              break;
  77:          }
  78:         bzero(buffer, N);
  79:   
  80:         if(recv(sockfd, buffer, N, 0) == -1)
  81:         {
  82:             perror("fail to recv");
  83:             exit(-1);
  84:         }
  85:         printf("-------->%s\n> ",buffer);
  86:     }
  87:     close(sockfd);
  88:   
  89:      return 0;
  90:  }
原文地址:https://www.cnblogs.com/pengdonglin137/p/2956417.html