Linux网络编程之IO复用循环服务器_第1页
Linux网络编程之IO复用循环服务器_第2页
Linux网络编程之IO复用循环服务器_第3页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、WORD格式1.介绍在前几节,我们介绍了循环效劳器,并发效劳器 . 简单的循环效劳器每次只能处理一个请求,即处理的请求是串行的。而并发效劳器可以通过创立多个进程或者是线程来并发的处理多个请求。但由于进程或线程的切换会带来一定的开销。 而且随着客户端请求的增多 ,创立的线程或进程的数目也越来越多,开销势必会增加。因此, 本文提出了 I/O 复用的循环效劳器。 I/O 复用的循环效劳器创立两个线程,一个是客户端连接处理线程,专门用来处理客户端的连接,当有客户端到来的时候,此线程把客户端的套接字描述符放到一块公共的区域中。另一个是业务处理线程,此线程轮循 (select) 客户端套接字描述符集合中有

2、没有数据到来,如果有数据到来,那么就进展处理。2. I/O 复用循环效劳器处理流程socket(.);bind(.);listen(.);pthread_create(.);pthread_join(.);close(.); / 关闭效劳器套接字连接处理线程 :while(1)accept(.);store(.);/ 存储客户端套接字描述符业务处理线程 :while(1)专业资料整理WORD格式get(.);/ 取出套接字描述符放到FD_SET专业资料整理WORD格式select(.);recv(.);process(.);send(.);close(.);从算法的主要流程可以看出,I/O 复

3、用循环效劳器只用两个线程,一个是请求业务连接线程,专门处理连接。另一个是业务处理线程,轮循客户端的套接字有没有数据。3. 相关例子效劳器 ;专业资料整理WORD格式#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/socket.h>#include <sys/types.h>#include <netinet/in.h>#include <time.h>#include <pthread.h>/*I/O 复用循

4、环效劳器I/O 并发效劳器随着客户端的增多,必须增加处理单元, 系统的负载会移动多个处理单元的切换上,专业资料整理WORD格式切换进程或者是线程专业资料整理WORD格式而 I/O 复用效劳器包括两个线程,一个是业务连接线程,专门处理客户端的连接,另一个是业务请求处理线程,对多个客户端描述符进展一定时间的等待,即select 监听多个描述符*/#define PORT 8888#define CLIENTNUM 1024专业资料整理WORD格式#define BUFFERSIZE 1024#define BACKLOG 10static int connect_hostCLIENTNUM;sta

5、tic int connect_number=0;/连接的客户数static void* handle_connect(void*argv)/ 业务连接函数,处理客户端的连接,将客户端的套接字描述符参加到连接池中int ret;int s;int sc;s=*(int*)argv);/效劳端套接字描述符int i=0;struct sockaddr_in client_addr;int len;len=sizeof(struct sockaddr_in);for(;)/ 监听有没有客户端到来sc=accept(s,(struct sockaddr*)&client_addr,&

6、len);printf("a client connect,from:%sn",inet_ntoa(client_addr.sin_addr);if(sc>0)for(i=0;i<CLIENTNUM;i+)if(connect_hosti=-1)connect_hosti=sc;connect_number+;break;/请求业务处理线程static void* handle_request(void*argv)time_t now;char bufferBUFFERSIZE;int size;专业资料整理WORD格式/设置轮循的时间,每隔1 秒struct

7、timeval tv;tv.tv_sec=1;tv.tv_usec=0;int ret;int i=0;int maxfd;fd_set scanfd;for(;)FD_ZERO(&scanfd);/清空文件描述符集合/ 将文件描述符放入文件描述符集合for(i=0;i<CLIENTNUM;i+)if(connect_hosti!=-1)FD_SET(connect_hosti,&scanfd);if(maxfd<connect_hosti)maxfd=connect_hosti;/selectret=select(maxfd+1,&scanfd,NULL,

8、NULL,&tv);/监控读文件描述符集,看看是否有数据可读switch(ret)case -1:/ 错误break;case 0:/ 超时break;default:/ 有数据到来if(connect_number<0)break;for(i=0;i<CLIENTNUM;i+)if(connect_hosti!=-1)if(FD_ISSET(connect_hosti,&scanfd)/文件描述符在文件集合中memset(buffer,0,BUFFERSIZE);size=recv(connect_hosti,buffer,BUFFERSIZE,0);if(siz

9、e>0&&!strncmp(buffer,"TIME",4)/时间请求专业资料整理WORD格式memset(buffer,0,BUFFERSIZE);now=time(NULL);sprintf(buffer,"%24srn",ctime(&now);send(connect_hosti,buffer,strlen(buffer),0);/更新文件描述符数组中的值connect_hosti=-1;connect_number-;close(connect_hosti);/关闭客户端套接字描述符break;int main(i

10、nt argc,char*argv)int ret;int s;struct sockaddr_in server_addr;int i;pthread_t thread2;/两个线程,一个是处理连接,另一个是处理请求/建立 TCP 套接字s=socket(AF_INET,SOCK_STREAM,0);memset(connect_host,-1,CLIENTNUM);/ 将存储套接字描述符的数组为 -1 if(s<0)perror("socket error");return -1;/将地址构造绑定到套接字描述符专业资料整理WORD格式server_addr.sin

11、_family=AF_INET;server_addr.sin_addr.s_addr=htonl(INADDR_ANY);server_addr.sin_port=htons(PORT);ret=bind(s,(struct sockaddr*)&server_addr,sizeof(struct sockaddr_in);if(ret<0)perror("bind error");return -1;/监听ret=listen(s,BACKLOG);if(ret<0)perror("listen error");return -1

12、;pthread_create(&thread0,NULL,handle_connect,(void*)&s);/处理客户端连接, 传递的是效劳器的套接字描述符pthread_create(&thread1,NULL,handle_request,NULL);/handle_request线程回调函数/等待线程完毕for(i=0;i<2;i+)pthread_join(threadi,NULL);close(s);客户端 :#include <stdio.h>#include <string.h>#include <stdlib.h&

13、gt;#include <sys/socket.h>专业资料整理WORD格式#include <sys/types.h>#include <time.h>#include <netinet/in.h>#define PORT 8888#define BUFFERSIZE 1024int main(int argc,char*argv)int s;int ret;int size;struct sockaddr_in server_addr;char bufferBUFFERSIZE;s=socket(AF_INET,SOCK_STREAM,0);

14、if(s<0)perror("socket error");return -1;bzero(&server_addr,sizeof(server_addr);/将地址构造绑定到套接字server_addr.sin_family=AF_INET;server_addr.sin_port=htons(PORT);server_addr.sin_addr.s_addr=htonl(INADDR_ANY);/连接效劳器ret=connect(s,(struct sockaddr*)&server_addr,sizeof(server_addr); if(ret

15、=-1)perror("connect error");return -1;memset(buffer,0,BUFFERSIZE);strcpy(buffer,"TIME");size=send(s,buffer,strlen(buffer),0);if(size<0)perror("send error");return -1;memset(buffer,0,BUFFERSIZE);专业资料整理WORD格式size=recv(s,buffer,BUFFERSIZE,0);if(size<0)perror("recv error");return;prin

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论