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

如何让做的网站自动适应浏览器云南住房建设厅网站

如何让做的网站自动适应浏览器,云南住房建设厅网站,网站建设技术知乎,网站伪静态有什么用目录 函数原型 poll服务器 对比select的优点 关于select的详解&#xff0c;可查看多路转接select服务器-CSDN博客 函数原型 #include <poll.h> int poll(struct pollfd *fds, nfds_t nfds, int timeout); poll作为多路转接的实现方案&#xff0c;与select要解决的问…

目录

函数原型

poll服务器

对比select的优点


关于select的详解,可查看多路转接select服务器-CSDN博客

函数原型

#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);

poll作为多路转接的实现方案,与select要解决的问题是一样的,同时它还要做到规避select的一些缺点

struct pollfd {int   fd;         /* file descriptor */short events;     /* requested events */short revents;    /* returned events */
};

这个数据结构中fd告诉了操作系统要关心fd上的事件,events是用户想关心的事件,有POLLIN,

POLLPRI,POLLOUT等等,这些都是宏

#define POLLIN		0x001		/* There is data to read.  */
#define POLLPRI		0x002		/* There is urgent data to read.  */
#define POLLOUT		0x004		/* Writing now will not block.  */

使用时,将events置为0,然后与POLLIN进行算数或运算,就表示告诉操作系统要关心fd的读事件,也可以关心同一个fd的多个事件,比如将events与POLLIN和POLLOUT都或一遍

看到这些宏定义,可以看出events也当成了位图来使用,每个比特位表示某种事件,值为1表示要关心这种事件,为0表示不关心

revents是操作系统返回的事件,表示fd上就绪了的事件,通过将revents与POLLIN进行算数与操作,就可知道写事件是否就绪

可以看出fds参数是一个指针,而后面的nfds参数实际上就是一个整型,这两个参数确定了一个pollfd的数组,pollfd包含了用户要关心哪些文件描述符的哪些事件的信息,还包含了操作系统告诉用户哪些事件就绪的信息。

timeout类似select,表示超时时间,以毫秒为单位

返回值与select一样,返回值为0表示超时返回;为-1表示有错误发生,并设置错误码errno;为正数表示在timeout时间内事件就绪的文件描述符个数

poll服务器

这里只给出poll_server的代码,其他文件的代码对理解poll不重要,只需要了解套接字的使用便可轻松看懂,若要查看其他文件的代码,详见rokobo/wsl_code - Gitee.com

poll服务器与select服务器有很强的相似性,有一个pollfd数组记录需要关心的文件描述符,此外大体思路与select相差不大,看代码可以理解

#include "socket.hpp"
#include "Log.hpp"
#include <poll.h>
#include <memory>
#include <cstring>
#include <cerrno>
#include <vector>
using namespace SocketModule;
using namespace LogModule;
class poll_server
{
public:poll_server():_listen_sock(std::make_shared<TcpSocket>()),_is_running(false),fds(NUM, {-1, 0, 0}){}void init(int port){_listen_sock->BuildTcpSocketMethod(port);fds[0].fd = _listen_sock->Fd();fds[0].events |= POLLIN;}void loop(){_is_running = true;int listenfd = _listen_sock->Fd();int timeout = 2000;while(_is_running){int ret = poll(fds.data(), fds.size(), timeout);if(ret == -1){LOG(LogLevel::ERROR) << "Error message: " << strerror(ret);continue;}else if(ret == 0){LOG(LogLevel::INFO) << "Time out\n";continue;}else{LOG(LogLevel::INFO) << "Dispatch begin\n";dispatcher();}}  }void accepter(int fd){InetAddr client;auto client_sock = _listen_sock->Accepter(&client);if(client_sock == nullptr){LOG(LogLevel::ERROR) << "Accept error";return;}int client_fd = client_sock->Fd();if(client_fd < 0){LOG(LogLevel::ERROR) << "Client fd error";return;}//将client_fd加入到fds中int i=0;for(i=0;i<NUM;++i){if(fds[i].fd == -1){fds[i].fd = client_fd;fds[i].events |= POLLIN;LOG(LogLevel::INFO) << "Accept success: " << client_sock->Fd() << " " << client.Addr();break;}}if(i == NUM){//扩容LOG(LogLevel::ERROR) << "fds is full";fds.resize(NUM * 2, {-1, 0, 0});            return;}}void recver(int who){int fd = fds[who].fd;std::string buffer;auto client_sock = std::make_shared<TcpSocket>(fd);ssize_t ret = client_sock->Recv(&buffer);if(ret == -1){LOG(LogLevel::ERROR) << "Recv error" << strerror(errno);client_sock->Close();//将fd从fds中删除fds[who].fd = -1;fds[who].events = 0;fds[who].revents = 0;return;}else if(ret == 0){LOG(LogLevel::INFO) << "Client closed: " << client_sock->Fd();client_sock->Close();//将fd从fds中删除fds[who].fd = -1;fds[who].events = 0;fds[who].revents = 0;return;}else{LOG(LogLevel::INFO) << "Recv success: " << buffer;return;}}void dispatcher(){//找到所有合法的fd,分发for(int i=0;i<NUM;++i){if(fds[i].fd == -1)continue;if(fds[i].revents & POLLIN){//分发给处理连接的函数if(fds[i].fd == _listen_sock->Fd()){accepter(fds[i].fd);}//分发给处理IO的函数else{recver(i);}}}}void stop(){}
private:std::shared_ptr<TcpSocket> _listen_sock;std::vector<pollfd> fds;bool _is_running;
};

主函数

#include "poll_server.hpp"
#include <string>
int main(int argc, char* argv[])
{if(argc != 2){std::cerr << "Usage: " << argv[0] << " <port>" << std::endl;return -1;}int port = std::stoi(argv[1]);if(port <= 0 || port > 65535){std::cerr << "Invalid port number" << std::endl;return -1;}poll_server s_svr;s_svr.init(port);s_svr.loop();return 0;
}

对比select的优点

poll解决了select关心的文件描述符数量有限的问题,可以向pollfd数组里添加随意添加元素,而且poll将输入参数与输出参数分离,events是输入参数,revents是输出参数,这样不需要像select一样每次调用前都清空,简化了编码


文章转载自:

http://2OmY6viy.dgmjm.cn
http://d2NksvFr.dgmjm.cn
http://TlgTVRGy.dgmjm.cn
http://dyfbFPFH.dgmjm.cn
http://CFBpTbqL.dgmjm.cn
http://XBjw2CuE.dgmjm.cn
http://IvDmUnAB.dgmjm.cn
http://5G2Z6aT9.dgmjm.cn
http://AbMD5WJu.dgmjm.cn
http://HBel791r.dgmjm.cn
http://zsqhhPNj.dgmjm.cn
http://1ZwOw28A.dgmjm.cn
http://xzsoXhN1.dgmjm.cn
http://c9fDUfE7.dgmjm.cn
http://0fl6B73U.dgmjm.cn
http://i3ZFQOjR.dgmjm.cn
http://bd8F1Aqf.dgmjm.cn
http://P1dv6X4m.dgmjm.cn
http://r7YuKUOi.dgmjm.cn
http://CTcqrcgE.dgmjm.cn
http://Y0sHy8a5.dgmjm.cn
http://IoMttFTO.dgmjm.cn
http://aFrgbEsE.dgmjm.cn
http://HYYKOtKS.dgmjm.cn
http://MxmSGsTE.dgmjm.cn
http://oaqvSigq.dgmjm.cn
http://vIjG0XpY.dgmjm.cn
http://JsyW69mo.dgmjm.cn
http://0kb38NHQ.dgmjm.cn
http://H9yoZ5Tw.dgmjm.cn
http://www.dtcms.com/wzjs/621428.html

相关文章:

  • wordpress仿站pdf城乡建设网站职业查询系统
  • 为自己做的网站申请域名wordpress修改网站标题
  • 网页设计和网站开发哪个好给公司做网站需要华多少钱
  • 中科互联网站建设专家康复中心网站建设方案
  • 苏州吴江太湖新城建设局网站通信工程企业网站建设
  • 海南景区网站建设方案手机开发者模式在哪里找
  • 网站链接查询厦门网站建设2015
  • 火山开发软件可以开发网站吗浏览器下载视频
  • 营销型网站的建设软文广州番禺桥南做网站
  • 免费推广平台排行aso优化费用
  • 宁波有哪些公司做网站怎么提高网站的收录量
  • 古城网站建设济南做网站创意
  • 网站建设问题及解决办法怎么登录甘肃省建设厅网站
  • 婚纱摄影网站定制seo关键词如何设置
  • 站长之家工具辽宁建设工程信息网外网公示时间
  • cpa广告网站怎么做godaddy域名注册
  • 网站流水怎么做个人免费发布房源信息
  • 网站ww正能量怎么样才能让百度收录自己的网站
  • 九江学网站建设自己做坑人网站的软件
  • 少儿编程自学网站戴尔公司网站建设成功的关键
  • 学校网站代码模板wordpress切换语言 语言包
  • 云南省住房和城乡建设厅网站首页网站 免费 托管运营
  • 网站建设方面书籍哪些网站百度不收录
  • 丽水专业网站建设价格wordpress 新窗口打开
  • 网站建设明细价单python兼职网站开发
  • 关于网站建设的网站有哪些企业网站建站 费用
  • 网站开发摊销期多少年开发区医院
  • 青岛西海岸新区建设网站潍坊搜易网站建设
  • 代做外国空间网站泉州建设工程质量网站
  • asp网站开发平台网站备案验证码错误