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。否则会提示线程方面的错误。

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

 

 

你可能感兴趣的:(Hello world)