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

下载本文档

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

文档简介

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

2、据到来,如果有数据到来,那么就进行处理。2. I/O复用循环服务器处理流程socket(.);bind(.);listen(.);pthread_create(.);pthread_join(.);close(.); /关闭服务器套接字连接处理线程:while(1)  accept(.);  store(.);/存储客户端套接字描述符业务处理线程:while(1) get(.);/取出套接字描述符放到FD_SET select(.); recv(.); process(.); send(.); close(.);从

3、算法的主要流程可以看出,I/O复用循环服务器只用两个线程,一个是请求业务连接线程,专门处理连接。另一个是业务处理线程,轮循客户端的套接字有没有数据。3. 相关例子服务器;#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并发服务器随着客户端的增多,必须增加处理单元,系统的负载会移动多个处理单元的切换上,切换进程或者是线程而I/O复用服务器包括两个线程,一个是业务连接线程,专门处理客户端的连接,另一个是业务请求处理线程,对多个客户端描述符进行一定时间的等待,即select监听多个描述符*/#define PORT 8888#define CLIENTNUM 1024#define BUFFERSIZE 1024#define BACKLOG 10static int connect_hostCLIENTNUM;static int connect_number=0;/连接的客户数static

5、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(;)/监听有没

6、有客户端到来     sc=accept(s,(struct sockaddr*)&client_addr,&len);     printf("a client connect,from:%sn",inet_ntoa(client_addr.sin_addr);          if(sc>0)         for(i

7、=0;i<CLIENTNUM;i+)              if(connect_hosti=-1)                     connect_hosti=sc;        

8、0;    connect_number+;             break;                                   /请求业务处理线程

9、static void* handle_request(void*argv)   time_t now;   char bufferBUFFERSIZE;   int size;  /设置轮循的时间,每隔1秒  struct timeval tv;  tv.tv_sec=1;  tv.tv_usec=0;  int ret;  int i=0;  int maxfd;  fd_set scanfd;  for(;)  

10、0;  FD_ZERO(&scanfd);/清空文件描述符集合     /将文件描述符放入文件描述符集合   for(i=0;i<CLIENTNUM;i+)    if(connect_hosti!=-1)        FD_SET(connect_hosti,&scanfd);        if(maxfd<connect_hosti)

11、0;           maxfd=connect_hosti;                      /select  ret=select(maxfd+1,&scanfd,NULL,NULL,&tv);/监控读文件描述符集,看看是否有数据可读  switch(ret)   

12、  case -1:/错误     break;    case 0:/超时    break;    default:/有数据到来        if(connect_number<0)         break;      for(i=0;i<CLIENTNUM;i+) 

13、           if(connect_hosti!=-1)                if(FD_ISSET(connect_hosti,&scanfd)/文件描述符在文件集合中                    memset(

14、buffer,0,BUFFERSIZE);                    size=recv(connect_hosti,buffer,BUFFERSIZE,0);                    if(size>0&&!strncmp(buffer,"

15、TIME",4)/时间请求                        memset(buffer,0,BUFFERSIZE);                        now=time(NULL);  

16、;                      sprintf(buffer,"%24srn",ctime(&now);                        send(connect_hosti,buffer,strlen(

17、buffer),0);                                        /更新文件描述符数组中的值                 

18、0;  connect_hosti=-1;                    connect_number-;                    close(connect_hosti);/关闭客户端套接字描述符       

19、60;                                 break;    int main(int argc,char*argv)  int ret;  int s;  struct sockaddr_in server_addr;  int i;  pthre

20、ad_t thread2;/两个线程,一个是处理连接,另一个是处理请求  /建立TCP套接字 s=socket(AF_INET,SOCK_STREAM,0); memset(connect_host,-1,CLIENTNUM);/将存储套接字描述符的数组为-1 if(s<0)   perror("socket error");   return -1; /将地址结构绑定到套接字描述符 server_addr.sin_family=AF_INET; server

21、_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)&#

22、160;  perror("listen error");   return -1;     pthread_create(&thread0,NULL,handle_connect,(void*)&s);/处理客户端连接,传递的是服务器的套接字描述符   pthread_create(&thread1,NULL,handle_request,NULL);/handle_request线程回调函数/等待线程结束  for(i=0;i<2;i+)&#

23、160;  pthread_join(threadi,NULL);close(s);客户端:#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/socket.h>#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); if(s<0)  perror("socket error");  return -1;bzero(&server_addr,sizeof(server_addr);/将地址结构绑定到套接

温馨提示

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

最新文档

评论

0/150

提交评论