在linux平台下,用多线程实现echo服务器与客户端“一对多”(即是一台服务器可以响应多个客户端的请求)。本人写了个demo,和大家一起分享,有不足的地方,请多多指教,我是壮壮熊。
编译时,在后面加上-lpthread。例如:g++ service2.cpp -o service2 -lpthread。否则会提示线程方面的错误。
echo服务器端代码:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<sys/socket.h> 4 #include<string.h> 5 #include<errno.h> 6 #include<netinet/in.h> 7 #include<arpa/inet.h> 8 #include<unistd.h> 9 #include<iostream> 10 #include<pthread.h> 11 using namespace std; 12 13 #define SERVERIP "192.168.1.117" 14 #define SERVERPORT 12345 15 #define MAXBUFFER 256 16 17 pthread_t ntid;//线程 18 int connfd;//客户端连接的ID 19 struct sockaddr_in clientaddr; 20 21 22 void *printContext(void *arg) 23 { 24 25 char ip[40]={0};//用来存放客户端连接的IP地址 26 char readBuf[MAXBUFFER]={0}; 27 int ret; 28 pthread_detach(ntid);//线程退出时,可以清理内存 29 int pconnfd=connfd;//客户端连接的ID(main函数中的accept的返回值) 30 //线程自己要保存连接符 ID,因为进程在第二个客户端 31 //连接后,会覆盖connfd 32 printf("%s ",inet_ntop(AF_INET,&clientaddr.sin_addr,ip,sizeof(ip))); 33 cout<<"connectd to the servce"<<endl; 34 35 while(ret=read(pconnfd,readBuf,MAXBUFFER))//读客户端发送的数据 36 { 37 write(pconnfd,readBuf,MAXBUFFER);//写回客户端 38 printf("%s ",readBuf);//打印传输的内容 39 bzero(readBuf,MAXBUFFER); 40 41 } 42 if(ret==0) 43 { 44 printf("the connection of client is close! "); 45 46 }else 47 { 48 printf("read error:%s ",strerror(errno)); 49 } 50 pthread_exit(0); 51 } 52 53 int main(int argc,char** argv) 54 { 55 socklen_t len;//socket长度类型 56 int serverFd,ret; 57 struct sockaddr_in serveraddr; 58 59 60 serverFd=socket(AF_INET,SOCK_STREAM,0);//创建socket 61 if(serverFd<0) 62 { 63 printf("socket error:%s ",strerror(errno)); 64 exit(-1); 65 } 66 67 bzero(&serveraddr,sizeof(serveraddr));//serveraddr清零 68 serveraddr.sin_family=AF_INET; 69 serveraddr.sin_port=htons(SERVERPORT); 70 inet_pton(AF_INET,SERVERIP,&serveraddr.sin_addr);//将C语言字节序转化成网络字节序 71 72 ret=bind(serverFd,(struct sockaddr *)&serveraddr,sizeof(serveraddr)); 73 if(ret!=0) 74 { 75 close(serverFd); 76 printf("bind error:% ",strerror(errno)); 77 exit(-1); 78 } 79 80 ret=listen(serverFd,5);//监听 81 if(ret!=0) 82 { 83 close(serverFd); 84 printf("listen error:%s ",strerror(errno)); 85 exit(-1); 86 } 87 //clientaddr清零 88 len=sizeof(clientaddr); 89 bzero(&clientaddr,sizeof(clientaddr)); 90 while(1) 91 { 92 //接收客户端的连接,然后启动线程去处理客户端发送的 93 //请求。线程只要保存connfd 即可。进程在第二个客户 端 94 //连接进来的时候,会覆盖第一个客户端的connfd 95 connfd=accept(serverFd,(struct sockaddr *) &clientaddr,&len); 96 if(connfd<0) 97 { 98 printf("accept error:%s ",strerror(errno)); 99 continue; 100 } 101 102 int err; 103 err=pthread_create(&ntid,NULL,printContext,NULL); 104 if(err!=0) 105 { 106 cout<<"can't create pthread"<<endl; 107 } 108 //close(connfd); 109 } 110 close(serverFd); 111 return 0; 112 }
客户端代码:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<sys/socket.h> 4 #include<string.h> 5 #include<errno.h> 6 #include<netinet/in.h> 7 #include<arpa/inet.h> 8 #include<unistd.h> 9 10 #define SERVERIP "192.168.1.117" 11 #define SERVERPORT 12345 12 #define MAXBUFFER 256 13 14 int main(int argc,char** argv) 15 { 16 int clientFd,ret; 17 struct sockaddr_in serveraddr; 18 char buf[MAXBUFFER]; 19 clientFd=socket(AF_INET,SOCK_STREAM,0);//创建socket 20 if(clientFd<0) 21 { 22 printf("socket error:%s ",strerror(errno)); 23 exit(-1); 24 } 25 26 bzero(&serveraddr,sizeof(serveraddr)); 27 serveraddr.sin_family=AF_INET; 28 serveraddr.sin_port=htons(SERVERPORT); 29 inet_pton(AF_INET,SERVERIP,&serveraddr.sin_addr); 30 31 //连接到服务器 32 ret=connect(clientFd,(struct sockaddr *)&serveraddr,sizeof(serveraddr)); 33 34 if(ret!=0) 35 { 36 close(clientFd); 37 printf("connect error:%s ",strerror(errno)); 38 exit(-1); 39 } 40 while(1) 41 { 42 bzero(buf,sizeof(buf)); 43 scanf("%s",buf); 44 write(clientFd,buf,sizeof(buf));//写数据 45 bzero(buf,sizeof(buf)); 46 read(clientFd,buf,sizeof(buf));//读数据 47 printf("echo:%s ",buf); 48 } 49 close(clientFd); 50 return (EXIT_SUCCESS); 51 52 }
再次提醒,编译时,在后面加上-lpthread。例如:g++ service2.cpp -o service2 -lpthread。否则会提示线程方面的错误。
如有转载,请注明出处,谢谢!