Linux网络编程--多线程实现echo服务器与客户端“一对多”功能,是网络编程的“Hello World!”

  在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\n",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\n",readBuf);//打印传输的内容
 39         bzero(readBuf,MAXBUFFER);
 40         
 41     }
 42     if(ret==0)
 43     {
 44         printf("the connection of client is close!\n");
 45         
 46     }else
 47     {
 48         printf("read error:%s\n",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\n",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:%\n",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\n",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\n",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 }
View Code

 

  客户端代码:

 

 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 \n",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 \n",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\n",buf);
48     }
49     close(clientFd);
50     return (EXIT_SUCCESS);
51     
52 }
View Code

 

  再次提醒,编译时,在后面加上-lpthread。例如:g++ service2.cpp -o service2 -lpthread。否则会提示线程方面的错误。

  如有转载,请注明出处,谢谢!

 

 

posted @ 2014-02-25 09:21  壮壮熊  阅读(1446)  评论(1编辑  收藏  举报