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

网站首页title沈阳市住房和城乡建设厅网站首页

网站首页title,沈阳市住房和城乡建设厅网站首页,做什么网站赚钱,临安网站建设公司1.前言 在本系列的前一篇文章中。介绍了libcurl对poll()的使用。參考libcurl原理解析(2) - libcurl对poll的使用。 本篇文章主要分析curl_poll()中对select()的封装使用。与前一篇类似#xff0c;我们仅仅分离出与select相关的代码。 2.curl_poll函数分析 这个函数… 1.前言 在本系列的前一篇文章中。介绍了libcurl对poll()的使用。參考libcurl原理解析(2) - libcurl对poll的使用。 本篇文章主要分析curl_poll()中对select()的封装使用。与前一篇类似我们仅仅分离出与select相关的代码。 2.curl_poll函数分析 这个函数中使用到的一些其他的数据结构能够參考前一篇文章中的介绍。本篇不再介绍。 /* 这个函数是对poll()的封装。假设poll()不存在则使用select()替代。 假设使用的是select()而且文件描写叙述符fd太大超过了FD_SETSIZE则返回error。 假设传入的timeout值是一个负数。则会无限的等待。直到没有有效的fd被提供。当发生 这样的情况(没有有效的fd)时。则负数timeout值会被忽略且函数会马上超时。 返回值 -1 系统调用错误或fdFD_SETSIZE. 0 timeout. N 返回的pollfd结构体的个数且当中的revents成员不为0. */ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms) { struct timeval pending_tv; struct timeval *ptimeout; fd_set fds_read; fd_set fds_write; fd_set fds_err; curl_socket_t maxfd; struct timeval initial_tv { 0, 0 }; bool fds_none TRUE; //用于验证传入的ufds数组是否有效 unsigned int i; int pending_ms 0; int error; //保存错误码 int r; //检測全部fd中是否存在有效的fd。 //假设至少存在一个有效的fd则fds_none置为false。停止检測 if (ufds) { for (i 0; i nfds; i) { if (ufds[i].fd ! CURL_SOCKET_BAD) { fds_none FALSE; break; } } } //假设全部的fd都是无效的(即bad socket, -1)。则等待一段时间后。直接返回。 if (fds_none) { r Curl_wait_ms(timeout_ms); //此函数会随后进行分析 return r; } //当传入的timeout值是一个负数(堵塞情形)或者0时。则无需衡量elapsed time. //否则获取当前时间。 if (timeout_ms 0) { pending_ms timeout_ms; initial_tv curlx_tvnow();//调用gettimeofday()或time()获取当前时间 } //每次调用select()前都须要又一次初始化fdset,由于它们既是输入參数又是输出參数。 FD_ZERO(fds_read); FD_ZERO(fds_write); FD_ZERO(fds_err); maxfd (curl_socket_t)-1; for (i 0; i nfds; i) { ufds[i].revents 0; if (ufds[i].fd CURL_SOCKET_BAD) //跳过无效的fd continue; VERIFY_SOCK(ufds[i].fd); //检測是否0fdFD_SETSIZE.超出这个范围。则返回-1. if (ufds[i].events (POLLIN | POLLOUT | POLLPRI | POLLRDNORM | POLLWRNORM | POLLRDBAND)) { if (ufds[i].fd maxfd) //获取到最大的fd,做为select()的第一个參数。 maxfd ufds[i].fd; if (ufds[i].events (POLLRDNORM | POLLIN)) FD_SET(ufds[i].fd, fds_read); if (ufds[i].events (POLLWRNORM | POLLOUT)) FD_SET(ufds[i].fd, fds_write); if (ufds[i].events (POLLRDBAND | POLLPRI)) FD_SET(ufds[i].fd, fds_err); } } //做为select()的timeout參数 ptimeout (timeout_ms 0) ? NULL : pending_tv; do { if (timeout_ms 0) { pending_tv.tv_sec pending_ms / 1000; pending_tv.tv_usec (pending_ms % 1000) * 1000; } else if (!timeout_ms) { pending_tv.tv_sec 0; pending_tv.tv_usec 0; } //真正调用select(). 第2。34參数已经在前面初始化(清空)过了。 r select((int)maxfd 1, fds_read, fds_write, fds_err, ptimeout); if (r ! -1) //select调用成功结束循环 break; //select调用失败。返回-1。通过errno能够获取到错误码。 error SOCKERRNO; //宏定义。#define SOCKERRNO (errno) //以下的error_not_EINTR 是宏定义. //#define error_not_EINTR (0 || error ! EINTR) if (error error_not_EINTR) //检測是否存在error且不是EINTR错误 break; //没有出错或者存在EINTR错误。则推断是否继续运行select() if (timeout_ms 0) { //elapsed_ms是宏定义。 //#define elapsed_ms (int)curlx_tvdiff(curlx_tvnow(), initial_tv) pending_ms timeout_ms - elapsed_ms; if (pending_ms 0) { r 0; //模拟select超时的情形 break; } } } while (r -1); /*如今能够对上面的这个while循环总结一下 1.假设select调用成功(即返回值0)则结束循环 2.假设select调用失败(即返回值-1)则检測errno是否为EINTR错误。 假设不是EINTR则结束循环。 假设是EINTR则检測是否已经超时。超时则结束循环没有超时则继续select()。 */ if (r 0) //select()调用失败 return -1; if (r 0) //select()超时 return 0; //select()调用成功, 统计当中状态发生改变的fd的个数保存至r. r 0; for (i 0; i nfds; i) { ufds[i].revents 0; if (ufds[i].fd CURL_SOCKET_BAD) continue; if (FD_ISSET(ufds[i].fd, fds_read)) //fd可读 ufds[i].revents | POLLIN; if (FD_ISSET(ufds[i].fd, fds_write)) //fd可写 ufds[i].revents | POLLOUT; if (FD_ISSET(ufds[i].fd, fds_err)) //fd出错 ufds[i].revents | POLLPRI; if (ufds[i].revents ! 0) r; } return r; } 这个函数运行完毕后。第一个输入參数ufds中的成员revents可能会被改动。最后。函数返回select()的实际返回值。 3.curl_wait_ms函数分析 以下是curl_wait_ms()函数的详细实现。也是基于poll或者select来实现的。这里也仅仅讨论它的select()实现版本号。 /* 这个函数用于等待特定的时间值。在函数Curl_socket_ready()以及Curl_poll()中被调用。 当没有提供不论什么fd来检測时。则仅仅是等待特定的一段时间。 假设是在windows平台下则winsock中的poll()以及select()超时机制须要一个有效的socket fd. 这个函数不同意无限等待假设传入的值是0或者负数。则马上返回。 超时时间的精度以及最大值。取决于系统。 返回值 -1 系统调用错误或无效的输入值(timeout)或被中断。 0 指定的时间已经超时 */ int Curl_wait_ms(int timeout_ms) { struct timeval pending_tv; struct timeval initial_tv; int pending_ms; int error; int r 0; if (!timeout_ms) //超时值为0马上返回 return 0; if (timeout_ms 0) //不能为负数 { SET_SOCKERRNO(EINVAL); return -1; } pending_ms timeout_ms; initial_tv curlx_tvnow(); do { pending_tv.tv_sec pending_ms / 1000; pending_tv.tv_usec (pending_ms % 1000) * 1000; r select(0, NULL, NULL, NULL, pending_tv); if (r ! -1) //select()调用成功则跳出循环 break; //select调用失败。返回-1。通过errno能够获取到错误码。 error SOCKERRNO; //宏定义。#define SOCKERRNO (errno) //以下的error_not_EINTR 是宏定义. #define error_not_EINTR (0 || error ! EINTR) if (error error_not_EINTR) 检測是否存在error且不是EINTR错误 break; //elapsed_ms是宏定义: //#define elapsed_ms (int)curlx_tvdiff(curlx_tvnow(), initial_tv) pending_ms timeout_ms - elapsed_ms; if (pending_ms 0) { r 0; //模拟select超时的情形 break; } } while (r -1); //确保返回值r仅仅能为-1(超时失败)或者0(超时成功)。 //r不可能大于0由于传入到select()函数的3个fdset数组所有都是NULL。假设select的返回值0,则说明调用出问题了。 //故这里会将r置为-1,即调用超时失败。 if (r) r -1; return r; }
http://www.pierceye.com/news/79913/

相关文章:

  • 专业微网站建设公司首选公司哪家好品牌网络营销案例分析
  • 网站商城支付接口网站的布局和配色
  • 网站建设的毕业设计报告家具行业建设网站
  • 网站不用域名需要备案吗魏县网站制作
  • 2019做seo网站山东省住房建设部网站
  • 网站开发系统规划望野王维原文
  • 运城网站推广wordpress 图片云存储
  • 定制网站建设济南室内设计联盟网
  • 龙岗附近网站建设建设网站主机
  • 零基础自己建网站优化免费网站建设
  • 上海市建设安装协会网站wordpress有手机版吗
  • 泰安网站seo如何与网站建立私密关系
  • 便利的网站建设沈阳大型网站建设
  • 做像百姓网这样网站多少钱做音乐网站之前的准备
  • 罗湖网站建设多少钱重庆渝北论坛
  • 建设公司网站都需要什么科目免费外贸网站建设
  • 班级同学录网站建设专业的企业智能建站制造厂家
  • 济南建立网站上海中国建设银行网站
  • 免费注册域名网站知乎唐山门户网站建设
  • 地方门户网站策划书丽水微信网站建设价格
  • 网站开发招标书网站开发 源代码
  • 苏州做网站推广哪家好郴州网站制作找工作
  • 有没有可以做app的网站什么网站做禽苗好的网站
  • 什么是网站静态页面凡科建站的模板 怎么弄下来
  • 六安哪家做网站不错wordpress静用字体
  • 怎么向百度提交网站地图零基础培训网页设计
  • 临沂网站设计价格广西人才网
  • 小说网站模板多种东莞微信网站建设
  • 工程建设网站导航图网站建设与管理实训报告总结
  • 杭州网站开发公司前端开发语言