博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于TCP的多进程echo服务器
阅读量:6974 次
发布时间:2019-06-27

本文共 5933 字,大约阅读时间需要 19 分钟。

服务器端:

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 
20:  #include 
21:  #include 
22:  #include 
23:  #include 
24:  #include 
25:  #include 
26:  #include 
27:   
28:  typedef struct sockaddr SA;  //
29:  #define N 128
30:   
31:  int main(int argc, char *argv[])
32:  {
33:      int listenfd, confd;  //定义listend用于存放监听套接字的描述符,confd用于存放accept返回的已建立连接套接字的描述符。
34:      struct sockaddr_in my_addr, peer_addr;//my_addr用于存放监听套接字要绑定的信息,peer_addr存放客户端套接字的信息
35:      socklen_t peer_len = sizeof(my_addr);  //peer_len最好定义时初始化,且必须初始化!
36:      char buffer[N]; //
37:   
38:      if(argc < 3)  //参数检查
39:      {
40:          printf("input error! %s 
\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:     signal(SIGCHLD, SIG_IGN);  //防止产生僵尸进程,告诉OS,当子进程结束时,将子进程的task_struct也一并回收。
78:   
79:     while(1)
80:     {
81:     /*
82:           当没有客户端请求时,服务器在此阻塞。直到有客户端请求,然后返回一个新的套接字描述符confd,与
83:           listenfd是相同类型的,但是confd可以用于与客户端收发数据,而listenfd不行,它只能监听。
84:           注意:accept返回的是一个新的已经与客户端建立连接的套接字confd,他有两个缓冲区,输入和输出,
85:           只有他才可以与客户端进行通信。他的类型与监听套接字一样。
86:     */
87:         if((confd = accept(listenfd, (SA *)&peer_addr, &peer_len)) < 0)
88:         {
89:             perror("accpt error!");
90:             exit(-1);
91:         }
92:   
93:         printf("client : [%s:%d] on line!\n",inet_ntoa(peer_addr.sin_addr), ntohs(peer_addr.sin_port));
94:
95:         if(fork() == 0)
96:         {
97:             while(recv(confd, buffer, N,0) > 0)  //将套接字confd的接收缓冲区的数据拷贝到buffer,当客户端关闭连接时,返回0。
98:             {
99:                 printf("client : [%s:%d]  > %s",inet_ntoa(peer_addr.sin_addr), ntohs(peer_addr.sin_port),buffer);
100:                 if(send(confd, buffer, N, 0) == -1)   //将buffer中的数据拷贝到confd的发送缓冲区
101:                 {
102:                     perror("fail to send");
103:                     exit(-1);
104:                 }
105:             }
106:   
107:            printf("client : [%s:%d] offline!\n",inet_ntoa(peer_addr.sin_addr), ntohs(peer_addr.sin_port));
108:              close(confd);
109:              exit(0);
110:         }
111:         close(confd);
112:     }
113:   
114:      return 0;
115:  }

 

 

客户端:

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 
20:  #include 
21:  #include 
22:  #include 
23:  #include 
24:  #include 
25:  #include 
26:  #include 
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 
\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:         //buffer[strlen(buffer) - 1] = '\0';
70:         if(send(sockfd, buffer, N, 0) == -1)
71:         {
72:             perror("fail to send");
73:             exit(-1);
74:         }
75:          if(strncmp(buffer, "quit", 4) == 0)
76:          {
77:              break;
78:          }
79:         bzero(buffer, N);
80:   
81:         if(recv(sockfd, buffer, N, 0) == -1)
82:         {
83:             perror("fail to recv");
84:             exit(-1);
85:         }
86:         printf("-------->%s> ",buffer);
87:     }
88:     close(sockfd);
89:   
90:      return 0;
91:  }

转载地址:http://buesl.baihongyu.com/

你可能感兴趣的文章
Java线程池
查看>>
解决方案:如何让ADC产品将HTTP请求负载的更加均衡
查看>>
开始运行你的第一个Java Web 项目
查看>>
PHP学习:$_GET,$_POST,$_REQUEST和$_SERVER的一些用法,以及parse_str方法
查看>>
java下DES加密与解密
查看>>
Nagios使用SendEmail发送邮件
查看>>
Domino8.5.1和Exchange2010共用一个邮件域实现邮件收发
查看>>
截图留存
查看>>
linux PDF转换为SWF
查看>>
ASP.net 中的AJAX学习记录之四 updateProgress控件的简单用法
查看>>
怎样自动生成makefile
查看>>
Windows2008R2 AD降级错误解决方案
查看>>
datagridview的数据库设计与使用
查看>>
资源管理器的学习笔记一
查看>>
JAVA中写时复制(Copy-On-Write)Map实现
查看>>
推荐12个漂亮的 CSS3 按钮实现方案
查看>>
顺序栈
查看>>
[译] OpenStack Kilo 版本中 Neutron 的新变化
查看>>
Lintcode: Sqrt(X)
查看>>
iOS:UIPageViewController翻页控制器控件详细介绍
查看>>