【多进程】

 

【多线程】

  1 /*************************************************************************
  2     > File summary: 多线程服务器
  3     > Author: 
  4     > Mail: xls0930@163.com 
  5     > Created Time: Sun 27 Jan 2019 10:08:19 PM CST
  6  ************************************************************************/
  7 
  8 #include<stdio.h>
  9 #include<string.h>
 10 #include<arpa/inet.h>
 11 #include<pthread.h>
 12 #include<ctype.h>
 13 #include<unistd.h>
 14 #include<fcntl.h>
 15 
 16 #define MAXLINE 8192
 17 #define SERV_PORT 8000
 18 
 19 struct s_info
 20 {
 21     struct sockaddr_in cliaddr;
 22     int connfd;
 23 };
 24 
 25 // 回调函数
 26 void *do_work(void *arg)
 27 {
 28     int n,i;
 29     struct s_info *ts = (struct s_info *)arg;
 30     char buf[MAXLINE];
 31     char str[INET_ADDRSTRLEN];
 32 
 33     while(1)
 34     {
 35         // 读出客户端的信息,关于read的返回值:返回n(n>0)表示读出n字节的数据,返回0表示已经读到结尾(可以理解为对端已关闭)
 36         n = read(ts->connfd,buf,MAXLINE);
 37         if(n == 0)
 38         {
 39             printf("the client %d close...\n", ts->connfd);
 40             //跳出循环
 41             break;
 42         }
 43         //打印输出客户端的ip+port
 44         printf("received from %s at PORT %d\n",
 45                 inet_ntop(AF_INET, &(*ts).cliaddr.sin_addr,str,sizeof(str)),
 46         
 47                 ntohs((*ts).cliaddr.sin_port));
 48         //对读出的信息进行小写转大写操作
 49         for(i = 0; i < n;i++)
 50         {
 51             buf[i] = toupper(buf[i]);
 52         }
 53         // 写到服务器的标准输出
 54         write(STDOUT_FILENO,buf,n);
 55         // 写回客户端
 56         write(ts->connfd,buf,n);
 57     }
 58     close(ts->connfd);
 59     return (void *)0;
 60 }
 61 
 62 int main()
 63 {
 64     struct sockaddr_in servaddr,cliaddr;
 65     socklen_t cliaddr_len;
 66     int listenfd,connfd;
 67     pthread_t tid;
 68 
 69     struct s_info ts[256];    // 创建结构体数组
 70     int i = 0;
 71 
 72     listenfd = socket(AF_INET,SOCK_STREAM,0);
 73 
 74     bzero(&servaddr, sizeof(servaddr));
 75     servaddr.sin_family = AF_INET;
 76     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
 77     servaddr.sin_port = htons(SERV_PORT);
 78 
 79     bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
 80 
 81     listen(listenfd, 128);
 82 
 83     printf("accepting client connect ...\n");
 84 
 85     while(1)
 86     {
 87         cliaddr_len = sizeof(cliaddr);
 88         // listenfd做监听,connfd与客户端进行读写操作,connfd中存放着客户端的信息
 89         connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);
 90         ts[i].cliaddr = cliaddr;
 91         ts[i].connfd = connfd;
 92 
 93         pthread_create(&tid,NULL,do_work,(void*)&ts[i]);
 94         // 回收子线程
 95         pthread_detach(tid);
 96         i++;
 97     }
 98     return 0;
 99 
100 }

我们可以使用nc命令来模拟客户端,对代码进行测试。

posted on 2019-01-28 09:57  我得去图书馆了  阅读(478)  评论(0编辑  收藏  举报