zoukankan      html  css  js  c++  java
  • 利用套接字实现进程通信一例

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

    先看看服务器端的程序:

       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:  }
  • 相关阅读:
    MYSQL
    数据中台的思考与总结
    基于SpringCloud分布式架构
    java常用工具库使用
    String性能提升10倍的几个方法
    Validator 注解使用
    【数据结构】trie树
    几种排序算法小结
    Core data的batch update
    UIScrollView和UIPageControl结合实现图片浏览
  • 原文地址:https://www.cnblogs.com/pengdonglin137/p/2956417.html
Copyright © 2011-2022 走看看