当前位置: 首页 > news >正文

广东阳江最新消息seo优化或网站编辑

广东阳江最新消息,seo优化或网站编辑,深圳专业定制建站公司,网站上的动态图怎么做的转载#xff1a;http://blog.csdn.net/michael_kong_nju/article/details/44887411 I/O复用技术 本文将讨论网络编程中的高级I/O复用技术#xff0c;将从下面几个方面进行展开#xff1a; a. 什么是复用技术呢#xff1f; b. 什么情况下需要使用复用技术呢#xff1f; c. …转载http://blog.csdn.net/michael_kong_nju/article/details/44887411 I/O复用技术 本文将讨论网络编程中的高级I/O复用技术将从下面几个方面进行展开 a. 什么是复用技术呢 b. 什么情况下需要使用复用技术呢 c. I/O的复用技术的工作原理是什么? d. select, poll and epoll的实现机制以及他们之间的区别。 下面我们以一个背景问题来开始 包括在以前的文章中我们讨论的案例都是阻塞式的I/O包括(fgetc/getc, fgets/gets)即当输入条件未满足时进程会阻塞直到满足之后进行读取但是这样导致的一个 问题是如果此时进程还有别的I/O信息需要读取那么这些信息将会被进程忽略掉。如何解决这个问题呢  可能这么说还是有点抽象我们针对之前的回射程序举个例子。程序在http://blog.csdn.net/michael_kong_nju/article/details/43457393 在正常连接的情况下客户端阻塞于fgets函数此时如果服务器终止我们发现客户端没有得到消息仍然阻塞 这个时候看下网络状态发现服务器已经结束而客户端处于CLOSE_WAIT状态。 而客户端此时得不到这个FIN的消息一直阻塞。而这是我们不希望看到那么这个问题该怎么解决呢 可以从下面几个条件来考虑 1.使用多进程或者多线程让不同的线程或者进程阻塞在不同的描述符上。 但是这种方法会造成程序的复杂而且进程和线程也需要OS资源的消耗如果访问请求过大的话那么很可能造成服务器的崩溃。Apache服务器是用的子进程的方式 其中的优点是在于不同的线程服务于不同的用户可以隔离用户。 2.用一个进程但是使用的是非阻塞的I/O读取数据 当一个I/O不可读的时候立刻返回检查下一个是否可读这种形式的循环为轮询polling这种方法比较浪费CPU时间因为大多数时间是不可读但是仍花费时间不断反复执行read系统调用。 3. 采用信号驱动式的I/O技术使用这种方法进程不会阻塞而是设置一个信号处理函数当I/O条件满足时由内核通知进程进行数据读取。但是这也会有一个问题如果请求很多的话那么需要的信号也很多。 4. 使用异步I/Oasynchronous I/O技术 和信号驱动式类似异步I/O技术也是使用信号进行通知进程但是不同的是这里只有一个阶段即当内核完成i/o操作之后会通知进程而不是就绪的时候。 关于2,3,4是另外的几种高级I/O技术我们将在后面的文章分别进行详细的讨论。 还有一种方法就是我们即将讨论的I/O多路复用技术下面先回答第一个问题 什么是复用技术呢 I/O复用技术是一种预先告知内核此进程需要进行哪些I/O并且当任何指定一个或多个I/O条件就绪时内核通知进程去进行处理的一种技术。他使得一个进程在不阻塞的 情况下处理多个描述符I/O. 针对上面的背景问题我们可以回答我们开始的第二个疑问 什么情况下需要使用复用技术呢 1当客户处理多个描述符时即上面的这种情况同时处理交互式输入和网络套接字。 2当客户需要处理多个套接字时。 3当服务器需要处理多个套接字时即并发服务器模型。 4当服务器需要同时处理TCP和UDP等不同的传输协议时也需要使用多路复用技术。 上面大概是几种需要使用多路复用技术的场景下面我们来讨论复用技术的实现原理。回答开头的第三个问题 I/O的复用技术的工作原理是什么? 下面这幅图是复用技术的工作模型可以看到这里是使用select来实现的当然也可以用epoll和poll来实现只是其中的具体细节不一样罢了。 下面我们开始回答最后一个问题 select, poll and epoll的实现机制以及他们之间的区别。 select函数 该函数准许进程指示内核等待多个事件中的任何一个发送并只在有一个或多个事件发生或经历一段指定的时间后才唤醒。函数原型如下 #include sys/select.h #include sys/time.hint select(int maxfdp1,fd_set *readset,fd_set *writeset,fd_set *exceptset,const struct timeval *timeout)返回值就绪描述符的数目超时返回0出错返回-1 函数参数介绍如下 1第一个参数maxfdp1指定待测试的描述字个数注意这里是个数是实际的最大的描述符加1和数组下标类似从0到maxfdp 共maxfd 1个所以这里是maxfd plus 1. 描述字0、1、2...maxfdp1-1均将被测试。在linux中头文件sys/select.h定义了最大的描述符是1024所以这里最大的maxfdp1也就是1025在互联网没有快速发展的时候这个值可能已经很大了但是在现在看来很容易就会实现这么大的并发所以select在很多条件下已经不能满足服务器的要求了所以出现了epoll这种无限制的机制。 2中间的三个参数readset、writeset和exceptset指定我们要让内核测试读、写和异常条件的描述字。如果对某一个的条件不感兴趣就可以把它设为空指针。struct fd_set可以理解为一个集合这个集合中存放的是文件描述符可通过以下四个宏进行设置 void FD_ZERO(fd_set *fdset);           //清空集合   例如 fd_set rset; FD_ZERO(set) ; 初始化将所有位置0 void FD_SET(int fd, fd_set *fdset);   //将一个给定的文件描述符加入集合之中   FD_SET(1, rset); 1bit开启。 void FD_CLR(int fd, fd_set *fdset);   //将一个给定的文件描述符从集合中删除 int FD_ISSET(int fd, fd_set *fdset);   // 检查集合中指定的文件描述符是否可以读写。 在select中集合是使用整数数组实现的数组中的每一个位都是一个int可以表示32bit即fd_set[0]可以用来表示0-31号描述符下面依次。 3timeout告知内核等待所指定描述字中的任何一个就绪可花多少时间。其timeval结构用于指定这段时间的秒数和微秒数。 struct timeval{ long tv_sec;   //seconds long tv_usec;  //microseconds }; 这个参数有三种可能 1永远等待下去仅在有一个描述字准备好I/O时才返回。为此把该参数设置为空指针NULL。 2等待一段固定时间在有一个描述字准备好I/O时返回但是不超过由该参数所指向的timeval结构中指定的秒数和微秒数。 3根本不等待检查描述字后立即返回这称为轮询。为此该参数必须指向一个timeval结构而且其中的定时器值必须为0。 下面看看描述有哪些就绪条件; 准备好读: 1,套接字接收缓冲区的数据字节数大于等于,套接字接收缓冲区低水位线,可以用SO_RCVLOWAT套接选项来设置低水位线,对于TCP和UDP套按字,默认值为1 2,该连接的读半部分关闭(接收到了FIN的TCP连接).对这样的套接字读操作,返回0(EOF) 3,该套接字是一个监听套接字且已经完成的连接数不为0.对这样的套按字的accept通常不会阻塞 4,其上有一个套接字错误街处理.对这样的套按字的读操作将不阻塞并返回-1(错误),同时把errno设置成错误条件,这些待处理错误也可以通过指定SO_ERROR套接字选项调用getsockopt获取. 准备好写: 1,该套接字发送缓冲区的可用字节数大于等于套接字发送缓冲区低水位线的当前大小.并且或者该套接已经连接,或者套按字不需要连接(UDP),如果我们把这套接字设置成非阻塞,写操作将不阻塞并返回一个正值.可以使用SO_SNDLOWAT设置一个该套接字的低水位标记.对于TCP和UDP默认值通常为2048. 2,该连接的写半部关闭.对这样的套接写的写操作将产生SIGPIPE信号. 3使用非阻塞式的connect的套按字已经建立连接,或者connect已经失败. 4,其上有一个套接字错误等处理,对这样的套接字进行写操作会返回-,且,把ERROR设置成错误条件,可以通过指定SO_ERROR套按选项调用getsockopt获取并清除. 上面都是理论的知识我们现在来看一个例子我们用select重写http://blog.csdn.net/michael_kong_nju/article/details/43457393 中的echo_tcp_client.c中的str_cli函数 [cpp] view plaincopy print? void   str_cli(FILE *fp, int sockfd)   {       int         maxfdp1;       fd_set      rset;       char        sendline[MAXLINE], recvline[MAXLINE];             FD_ZERO(rset);       for ( ; ; ) {           FD_SET(fileno(fp), rset);           FD_SET(sockfd, rset);           maxfdp1  max(fileno(fp), sockfd)  1;           select(maxfdp1, rset, NULL, NULL, NULL);                 if (FD_ISSET(sockfd, rset)) {  /* socket is readable */               if (read(sockfd, recvline, MAXLINE)  0)               {                          perror(str_cli: server terminated prematurely);                       exit(1);               }                       fputs(recvline, stdout);           }                 if (FD_ISSET(fileno(fp), rset)) {  /* input is readable */               if (fgets(sendline, MAXLINE, fp)  NULL)                   return;     /* all done */               write(sockfd, sendline, strlen(sendline));           }       }   }   限于篇幅的原因这里不给出客户端的main函数但是我们建议你去我的github中下载这个我已经展开过的源码去调试运行一下 https://github.com/michaelnju/UNPV-Relaxing-Code/blob/master/Chaper6_Select_Test/select_echo_tcp_cli.c 服务器程序还是用上一个连接中的。 这时候你会看到在客户端和服务器正常连接的过程中如果这时候服务器断开了那么客户端会立马被告知而不像我们刚开始的时候那样会阻塞。 所以我们看到了select的作用。下篇文章我们将看到select在并发服务器中的作用。 完整的客户端代码 //#include unp.h   /*   Lingtao relax this code in 2015   */   #include stdio.h   #include sys/types.h   #include sys/socket.h   #include netinet/in.h   #include sys/select.h   #include sys/time.h       #define LISTENQ 5   #define MAXLINE 2048   #define SERV_PORT 9877   #define max(a,b) ((a) (b) ? (a) : (b))       typedef struct sockaddr SA;       void   str_cli(FILE *fp,int sockfd)   {   int maxfdp1;   fd_set rset;   char sendline[MAXLINE], recvline[MAXLINE];       FD_ZERO(rset);   for ( ; ; ) {   FD_SET(fileno(fp), rset);   FD_SET(sockfd, rset);   maxfdp1 max(fileno(fp), sockfd) 1;   select(maxfdp1, rset, NULL, NULL, NULL);       if (FD_ISSET(sockfd, rset)) {/* socket is readable*/   if (read(sockfd, recvline, MAXLINE) 0)   {   perror(str_cli: server terminated prematurely);   exit(1);   }   fputs(recvline, stdout);   }       if (FD_ISSET(fileno(fp), rset)) {/* input is readable*/   if (fgets(sendline, MAXLINE, fp) NULL)   return; /* all done */   write(sockfd, sendline, strlen(sendline));   }   }   }       int   main(int argc,char **argv)   {   int sockfd;   struct sockaddr_in servaddr;       if (argc ! 2)   {   perror(usage: tcpcli IPaddress);   exit(1);   }   sockfd socket(AF_INET, SOCK_STREAM,0);       bzero(servaddr, sizeof(servaddr));   servaddr.sin_family AF_INET;   servaddr.sin_port htons(SERV_PORT);   inet_pton(AF_INET, argv[1], servaddr.sin_addr);       connect(sockfd, (SA *) servaddr,sizeof(servaddr));   str_cli(stdin, sockfd); /* do it all */       exit(0);   }
http://www.pierceye.com/news/17366/

相关文章:

  • google网站收录门户类网站模板
  • python 建设网站如何建广告网站
  • 论坛网站制作模板logo图案免费
  • 深圳企业网站定制廊坊酒店网站建设
  • 陕西建设网网站集群哪里发布网站开发需求
  • 做网站买什么服务器 便宜在哪里可以学做网站
  • 手机怎么建网站21dove谁做的的网站
  • 网站制作需要多少钱新闻广告运营推广
  • 科技网站建设+长沙青岛网站建设软件
  • 网站建设的ci设计指的是什么成都顶呱呱网站建设
  • 做app的网站有哪些功能seo网站内部优化
  • 网站引导动画怎么做的700个吉祥公司名字
  • 郑州定制网站开发福州网站建设 联系yanktcn 04
  • 白银市建设网站企业年报系统官网入口
  • 可口可乐网站建设目的公司网站域名无法解析
  • 买过域名之前就可以做网站了吗?什么 门户网站
  • 网站设计ai做暧暧小视频网站
  • 湖南平台网站建设找哪家打开连接 wordpress
  • 门户网站开发注意哪些网站开发建设企业
  • 扁平化资讯网站模板图片网站php源码
  • centos wordpress安装教程网站优化防范
  • 如何做网站搜索引擎优化免费网站建设代理
  • 网站节点加速湛江建设网官方网站
  • 上市企业网站设计安徽海川建设公司网站
  • 做网站找客源一套完整的app开发流程
  • 网站建设实践报告哈尔滨企业做网站
  • 昆明专业建站wordpress文章输入密码可见
  • 石河子做网站的公司网站设计与制作的过程
  • 河南网站建设yijuce高质量关键词搜索排名
  • 扒网站样式上海备案证查询网站查询网站查询系统