zoukankan      html  css  js  c++  java
  • 多线程编写回射客户端程序

    用多线程实现回射客户端程序
    int pthread_detach(pthread_t thread);

    客户端不变:

     1 #include<unistd.h>
     2 #include<sys/types.h>
     3 #include<sys/socket.h>
     4 #include<string.h>
     5 #include<stdlib.h>
     6 #include<stdio.h>
     7 #include<errno.h>
     8 #include<netinet/in.h>
     9 #include<arpa/inet.h>
    10 #define ERR_EXIT(m)
    11     do
    12     {
    13         perror(m);
    14         exit(EXIT_FAILURE);
    15     }while(0)
    16 int main(void)
    17 {
    18     int sock;//客户端创建套接字
    19     if((sock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))<0)
    20         ERR_EXIT("socket error");
    21     
    22     struct sockaddr_in servaddr;//本地协议地址赋给一个套接字
    23     memset(&servaddr,0,sizeof(servaddr));
    24     servaddr.sin_family=AF_INET;
    25     servaddr.sin_port=htons(5188);
    26     
    27     servaddr.sin_addr.s_addr=inet_addr("127.0.0.1");//服务器段地址
    28     //inet_aton("127.0.0.1",&servaddr.sin_addr);
    29     
    30     if(connect(sock,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
    31         ERR_EXIT("connect");
    32     char sendbuf[1024]={0};
    33     char recvbuf[1024]={0};
    34     while(fgets(sendbuf,sizeof(sendbuf),stdin)!=NULL)//默认有换行符
    35     {
    36         write(sock,sendbuf,strlen(sendbuf));
    37         read(sock,recvbuf,sizeof(recvbuf));
    38         fputs(recvbuf,stdout);
    39 
    40         memset(sendbuf,0,sizeof(sendbuf));
    41         memset(recvbuf,0,sizeof(recvbuf));
    42     }
    43     close(sock);
    44     
    45     return 0;
    46 }

    服务器端当有新连接到来的时候,新建一个线程,并且在这个线程的入口函数中来处理连接:

     1 #include<unistd.h>
     2 #include<sys/types.h>
     3 #include<sys/socket.h>
     4 #include<netinet/in.h>
     5 #include<arpa/inet.h>
     6 #include<stdlib.h>
     7 #include<stdio.h>
     8 #include<errno.h>
     9 #include<string.h>
    10 #include<pthread.h>
    11 #define ERR_EXIT(m)
    12     do
    13     {
    14         perror(m);
    15         exit(EXIT_FAILURE);
    16     }while(0)
    17 
    18 void echo_srv(int conn)
    19 {
    20     char recvbuf[1024];
    21     while(1)
    22     {
    23         memset(recvbuf,0,sizeof(recvbuf));
    24         int ret=read(conn,recvbuf,sizeof(recvbuf));
    25         if(ret==0)
    26         {
    27             printf("client close
    ");
    28             break;
    29         }
    30         else if(ret==-1)
    31         {
    32             ERR_EXIT("read");
    33         }
    34         fputs(recvbuf,stdout);
    35         write(conn,recvbuf,ret);
    36     }
    37 
    38 }
    39 void*  thread_routine(void* arg)
    40 {
    41     //当前新线程设置为分离状态,防止僵死
    42     pthread_detach(pthread_self());
    43     //int conn=(int)arg;
    44     int conn=*(int*)arg;
    45     free(arg);
    46     echo_srv(conn);
    47     printf("exiting thread...
    ");
    48     return NULL;
    49 }
    50 int main(void)
    51 {
    52     int listenfd;
    53     if((listenfd=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))<0)
    54         ERR_EXIT("socket");
    55     struct sockaddr_in servaddr;
    56     memset(&servaddr,0,sizeof(servaddr));
    57     servaddr.sin_family=AF_INET;
    58     servaddr.sin_port=htons(5188);
    59     servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
    60     
    61     int on=1;
    62     if(setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0)
    63         ERR_EXIT("setsockopt");
    64     
    65     if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
    66         ERR_EXIT("bind");
    67     if(listen(listenfd,SOMAXCONN)<0)
    68         ERR_EXIT("listen");
    69 
    70     struct sockaddr_in peeraddr;
    71     socklen_t peerlen=sizeof(peeraddr);
    72     int conn;
    73     while(1)
    74     {
    75         if((conn=accept(listenfd,(struct sockaddr*)&peeraddr,&peerlen))<0)
    76             ERR_EXIT("accept");
    77         printf("ip=%s port=%d
    ",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port));
    78         pthread_t tid;
    79         int ret;
    80         //不传递(void*)&conn的原因,有新的连接的话conn发生改变,如过新的线程没有把conn取走的话,conn就改变了
    81         //较好的方案
    82         int * p=malloc(sizeof(int));
    83         *p=conn;
    84         ret=pthread_create(&tid,NULL,thread_routine,(void*)p);
    85         //ret=pthread_create(&tid,NULL,thread_routine,(void*)conn);
    86         
    87         if(ret!=0)
    88         {
    89             fprintf(stderr,"pthread_create%s
    ",strerror(ret));
    90             exit(EXIT_FAILURE);
    91         }
    92         
    93     }
    94     return 0;
    95 }
  • 相关阅读:
    Spring IOC(二)beanName 别名管理
    Spring IOC(六)依赖查找
    Spring IOC(五)依赖注入
    Spring IOC(七)类型推断
    Spring 循环引用(二)源码分析
    Spring 循环引用(一)一个循环依赖引发的 BUG
    Spring IOC(四)FactoryBean
    Spring 中的类加载机制
    Spring IOC(三)单例 bean 的注册管理
    Spring Environment(三)生命周期
  • 原文地址:https://www.cnblogs.com/wsw-seu/p/8496008.html
Copyright © 2011-2022 走看看