zoukankan      html  css  js  c++  java
  • 客户端和服务器实现全双工通信(基于线程)

    http://blog.sina.com.cn/s/blog_87766e4a0100yp7a.html

    1、 基于多线程实现一个服务器和一个客户端实现全双工通信

    服务器端创建两个线程:一个用于接收客户端发送过来的信息;一个用来给客户端发送信息。

    客户端也创建两个线程:一个用于接收服务器端发送过来的信息;一个用来给服务器端发送信息。

     

    2、 示例代码

    服务器端的代码client.c

    #include <sys/types.h>

    #include <sys/socket.h>

    #include <stdio.h>

    #include <stdlib.h>

    #include <errno.h>

    #include <string.h>

    #include <unistd.h>

    #include <netinet/in.h>

    #define SERVPORT 3333

    #define BACKLOG 10                 //请求队列中的最大请求数

    #define MAX_CONNECTED_NO 10  //最大是128台电脑连接

    #define MAXDATASIZE 100

     

    void pthread_recv(void *arg);

    void Pthread_send(void * arg);

     

    int main()

    {

             struct sockaddr_in server_sockaddr,client_sockaddr;

             int sockfd,client_fd,sin_size,ret;

             pthread_t id1,id2;

             sin_size =sizeof(struct sockaddr);

             //struct sockaddr_in server_sockaddr,client_sockaddr;

             //建立一个socket连接

         //目前都是AF_INET(ipv4);SOCK_STREAM(TCP),如果是UDP,则SOCK_DGRAM

             if((sockfd = socket(AF_INET,SOCK_STREAM,0))==-1){

                       perror("socket");

                       exit(1);

             }

             printf("socket success!,sockfd=%d ",sockfd);

             //bind用于本地IP地址和端口的绑定

             server_sockaddr.sin_family=AF_INET;

             server_sockaddr.sin_port=htons(SERVPORT);

             server_sockaddr.sin_addr.s_addr=INADDR_ANY;         //htonl(INADDR_ANY)

         bzero(&(server_sockaddr.sin_zero),8);

             //把本端的信息绑定

             if(bind(sockfd,(struct sockaddr *)&server_sockaddr,sizeof(struct sockaddr))==-1)

          {              

               perror("bind");

                   exit(1);

             }

             printf("bind success! ");

             if(listen(sockfd,BACKLOG)==-1)

         {

                       perror("listen");

                       exit(1);

             }

             printf("listening.... ");

         //接受并保存客户端的信息

             if((client_fd=accept(sockfd,(struct sockaddr *)&client_sockaddr,&sin_size))==-1)

         {                

    perror("accept");

                    exit(1);

             }

             printf("client_fd=%d",client_fd);

             pthread_create(&id1,NULL,(void *) pthread_recv,(void*)&client_fd);

             if(ret != 0)

                       perror("pthread_recv creat");

             ret=pthread_create(&id2,NULL,(void *)Pthread_send,(void*)&client_fd);

             if(ret != 0)

                       perror("Pthread_send creat");

             pthread_join(id1,NULL);

             pthread_join(id2,NULL);

             close(sockfd);

    }

     

    //服务器发送线程

    void Pthread_send(void * arg)

    {

             int buf_len, client_fd,sendbytes;

             char buf[MAXDATASIZE];

             client_fd = *((int *)arg);

             printf("server send: ");

             while(1)

             {       

                       fgets(buf,MAXDATASIZE,stdin);

                       buf_len =sizeof(buf);

                       if((sendbytes = send(client_fd ,buf,buf_len,0))==-1)

                       {

                                perror("send");

                                exit(1);

                       }

                       if(!strncmp(buf,"end",3))         //只比较字符串的前三个字符

                                break;

                       sleep(2);

             }

                               

    }

     

    //服务器接收数据线程

    void pthread_recv(void *arg)

    {

             int buf_len, client_fd,recvbytes;

             char buf[MAXDATASIZE];

             client_fd = *((int *)arg);

         //接收服务端发来的信息

             while(1)

             {

                       if((recvbytes = recv(client_fd ,buf,MAXDATASIZE,0))==-1)

                       {

                                perror("recv");

                                exit(1);

                       }

                       else

                       {

                                buf[recvbytes]=0;

                                printf("server received data from server is :%s ",buf);

                                if(!strncmp(buf,"end",3))         //只比较字符串前三个字符

                                         break;

                       }

                       sleep(1);

             }

    }

     

    客户端的代码:

    #include <stdio.h>

    #include <stdlib.h>

    #include <errno.h>

    #include <string.h>

    #include <netdb.h>

    #include <sys/types.h>

    #include <netinet/in.h>

    #include <sys/socket.h>

     

    #define SERVPORT 3333

    #define MAXDATASIZE 100

     

    void pthread_recv(void *arg);

    void Pthread_send(void * arg);

     

    main(int argc,char *argv[]){

             int sockfd,sin_size,ret;

             struct hostent *host;

             pthread_t id1,id2;

             struct sockaddr_in serv_addr;         //套接字的地址结构

             struct sockaddr_in server_sockaddr;

            

             if(argc < 2)

        {

                       fprintf(stderr,"Please enter the server's hostname! ");

                       exit(1);

             }       

         //AF_INET:使用的是IPV4

         //SOCK_STREAM:流式套接字

             if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)

         {

              perror("socket");

                     exit(1);

             }

             printf("sockfd=%d ",sockfd);

             serv_addr.sin_family=AF_INET;

             serv_addr.sin_port=htons(SERVPORT);

         //serv_addr.sin_addr=*((struct in_addr *)host->h_addr);

         //host->h_addr强制类型转换;建议直接使用下面的方法

             serv_addr.sin_addr.s_addr=inet_addr(argv[1]);   //"127.0.0.1");       Internet地址

             bzero(&(serv_addr.sin_zero),8);

         //连接

             if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))==-1)

             {

                       perror("connect");

                       exit(1);

             }

             ret=pthread_create(&id1,NULL,(void *)Pthread_send,(void*)&sockfd);

             if(ret != 0)

                       perror("Pthread_send creat");

             pthread_create(&id2,NULL,(void *) pthread_recv,(void*)&sockfd);

             if(ret != 0)

                       perror("pthread_recv creat");

             pthread_join(id1,NULL);

             pthread_join(id2,NULL);

             close(sockfd);

    }

     

    //客户端发送数据线程

    void Pthread_send(void * arg)

    {

             int buf_len, sockfd,sendbytes;

             char buf[MAXDATASIZE];

             sockfd = *((int *)arg);

             printf("client send: ");

             while(1)

             {       

                       fgets(buf,MAXDATASIZE,stdin);

                       buf_len =sizeof(buf);

                       if((sendbytes = send(sockfd,buf,buf_len,0))==-1)

                       {

                                perror("send");

                                exit(1);

                       }

                       if(!strncmp(buf,"end",3))         //只比较字符串的前三个字符

                                break;

                       sleep(2);

             }                   

    }

     

    //客户端接收数据线程

    void pthread_recv(void *arg)

    {

             int buf_len, sockfd,recvbytes;

             char buf[MAXDATASIZE];

             sockfd = *((int *)arg);

         //接收服务端发来的信息

             while(1)

             {

                       if((recvbytes = recv(sockfd,buf,MAXDATASIZE,0))==-1)

                       {

                                perror("recv");

                                exit(1);

                       }

                       else

                       {

                                buf[recvbytes]=0;

                               printf("client received data from server is :%s ",buf);

                                if(!strncmp(buf,"end",3))         //只比较字符串的前三个字符

                                         break;

                       }

                       sleep(1);

             }

    }

  • 相关阅读:
    Git-本地项目和远程项目关联
    P1-Linux下安装MySQL及登录用户配置
    P2-Centos中安装vsftpd
    ElasticSearch安装及HEAD插件配置
    ArrayList源码分析
    Maven的继承以及import作用域
    单例模式浅析
    Vim快捷键记录(工作中遇到)
    OSX下 pip更新及安装python库
    统计工具之QQ图
  • 原文地址:https://www.cnblogs.com/feng9exe/p/7612543.html
Copyright © 2011-2022 走看看