zoukankan      html  css  js  c++  java
  • 【网络编程三】网络通信之多进程(线程)实现TCP通信(一)

    【多进程】

    【多线程】

      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...
    ", ts->connfd);
     40             //跳出循环
     41             break;
     42         }
     43         //打印输出客户端的ip+port
     44         printf("received from %s at PORT %d
    ",
     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 ...
    ");
     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命令来模拟客户端,对代码进行测试。

  • 相关阅读:
    Java-列出所有系统属性
    Java-一个数组中的元素复制到另一个数组
    Java-将字符串转为数字
    Java单例模式简单实现
    Spring注解@Component、@Repository、@Service、@Controller
    VisualGDB系列2:VisualGDB对Linux平台的支持特性
    VisualGDB系列1:VisualGDB总体概述
    Docker入门(七):部署app
    Docker入门(六):Stacks
    Docker入门(五):Swarms
  • 原文地址:https://www.cnblogs.com/xuelisheng/p/10328950.html
Copyright © 2011-2022 走看看