码迷,mamicode.com
首页 > 编程语言 > 详细

客户端和服务器实现全双工通信(基于线程)

时间:2017-09-29 21:18:22      阅读:404      评论:0      收藏:0      [点我收藏+]

标签:创建   stream   实现   ipv4   printf   std   blog   套接字   listening   

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\n",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!\n");

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

     {

                   perror("listen");

                   exit(1);

         }

         printf("listening....\n");

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

         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\n",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!\n");

                   exit(1);

         }       

     //AF_INET:使用的是IPV4

     //SOCK_STREAM:流式套接字

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

     {

          perror("socket");

                 exit(1);

         }

         printf("sockfd=%d\n",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\n",buf);

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

                                     break;

                   }

                   sleep(1);

         }

}

客户端和服务器实现全双工通信(基于线程)

标签:创建   stream   实现   ipv4   printf   std   blog   套接字   listening   

原文地址:http://www.cnblogs.com/feng9exe/p/7612543.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!