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

做门用什么网站好全球互联网企业100强名单

做门用什么网站好,全球互联网企业100强名单,中文域名注册官网入口,股票实时交易网站开发目录 select函数原型 select服务器 select的缺点 前面介绍过多路转接就是能同时等待多个文件描述符&#xff0c;这篇文章介绍一下多路转接方案中的select的使用 select函数原型 #include <sys/select.h> int select(int nfds, fd_set *readfds, fd_set *writefds, f…

目录

select函数原型

select服务器

select的缺点


前面介绍过多路转接就是能同时等待多个文件描述符,这篇文章介绍一下多路转接方案中的select的使用

select函数原型

#include <sys/select.h>
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set
*exceptfds, struct timeval *timeout);

先介绍一下各个参数以及返回值

多路转接需要等待多个文件描述符的事件就绪,所以用户势必需要告诉操作系统,他关心的是哪些文件描述符,以及关心这些文件描述符上的读事件还是写事件。读事件就绪就是这个文件描述符的缓冲区不为空有数据能读,写事件就绪就是缓冲区不为满可以写入。除了这两种常见的事件外,还可以关心某个文件描述符的异常事件。

再来看select的参数,nfds是一个整数,可以告诉操作系统需要关心哪些文件描述符,具体来说,nfds是需要关心的文件描述符的最大值 + 1,可以预想到select函数会遍历小于等于nfds - 1的文件描述符,查看是否有事件就绪

struct timeval {time_t      tv_sec;  /* Seconds */          //秒suseconds_t tv_usec; /* Microseconds */     //毫秒
};

timeout表示select的等待时间,timeout也可为空,表示阻塞等待直到某个文件描述符发生事件,timeout为0表示不等待事件发生,其他自定义值表示若在这段时间内没有事件发生,则超时返回。

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

为了介绍剩下的三个参数,先介绍一下fd_set

我们已经通过fds告诉操作系统要关心哪些文件描述符,timeout设置了等待时间,现在还需要告诉操作系统要关心哪些文件描述符的读事件或写事件

从抽象的层面上理解,fd_set是一个集合,是一个文件描述符的集合,readfds是关心读事件的文件描述符集合,writefds是关心写事件的文件描述符集合,exceptfds是关心异常事件的文件描述符集合。

还需要指出,这三个参数还是输出型参数,操作系统会将等待后事件就绪的文件描述符加入集合,

比如关心4,5,6的读事件,若就绪了4和5,集合就会变成4,5,这也为写代码带来了麻烦

从具体实现上来看,fd_set是一个位图,有若干个比特位表示文件描述符,值为1表示关心这个文件描述符,为0表示不关心,举个例子

00011111001

下标从0开始的话,这个位图表示关心3,4,5,6,7,10号文件描述符,其余的都不关心

/* fd_set for select and pselect.  */
typedef struct{/* XPG4.2 requires this member name.  Otherwise avoid the namefrom the global namespace.  */
#ifdef __USE_XOPEN__fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->fds_bits)
#else__fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->__fds_bits)
#endif} fd_set;

fd_set封装了一个大小固定的数组,数组的每个比特位都可以记录是否关心这个文件描述符

作为用户,想对fd_set操作,操作系统也提供了相关的接口

// 将文件描述符fd从集合set中删除
void FD_CLR(int fd, fd_set *set);
// 判断文件描述符fd是否在集合set中
int  FD_ISSET(int fd, fd_set *set);
// 将fd放入集合set中
void FD_SET(int fd, fd_set *set);
// 清空集合set
void FD_ZERO(fd_set *set);

select服务器

到这里,select已经可以等待多个文件描述符的一些事件了,可以来搭一个简单的服务器,接收多个用户的消息,回显在屏幕上

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

在这份代码中,需要等待的事件有等待客户端的连接和等待客户端发消息,由于连接建立后会创建文件描述符,文件描述符会变多,需要一个数据结构把这些文件描述符管理起来,这里选择了原生数组,因为可以直观的感受到select的缺点之一,存在大量遍历,性能不够高。

#include "socket.hpp"
#include "Log.hpp"
#include <sys/select.h>
#include <memory>
#include <cstring>
#include <cerrno>
using namespace SocketModule;
using namespace LogModule;class select_server
{
// sizeof可以得到底层数组的字节数,乘8得到比特数
static const int NUM = sizeof(fd_set) * 8;
public:select_server():_listen_sock(std::make_shared<TcpSocket>()),_is_running(false){}void init(int port){_listen_sock->BuildTcpSocketMethod(port);for(int i=0;i<NUM;++i){fds[i] = -1;}//初始只需要关心_listen_sock这一个文件描述符fds[0] = _listen_sock->Fd();}void loop(){_is_running = true;int listenfd = _listen_sock->Fd();fd_set readset;while(_is_running){//readset作为输出参数,select返回后可能被修改,需要清空后重新设置FD_ZERO(&readset);int max_fd = 0;for(int i=0;i<NUM;++i){if(fds[i] != -1){max_fd = fds[i] > max_fd ? fds[i] : max_fd;FD_SET(fds[i], &readset);}}struct timeval timeout = {2, 0};int ret = select(max_fd + 1, &readset, nullptr, nullptr, &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(readset);}}  }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中//如果fds满了,关闭连接int i=0;for(i=0;i<NUM;++i){if(fds[i] == -1){fds[i] = client_fd;LOG(LogLevel::INFO) << "Accept success: " << client_sock->Fd() << " " << client.Addr();break;}}if(i == NUM){LOG(LogLevel::ERROR) << "Too many connections";client_sock->Close();return;}}void recver(int who){int fd = fds[who];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] = -1;return;}else if(ret == 0){LOG(LogLevel::INFO) << "Client closed: " << client_sock->Fd();client_sock->Close();//将fd从fds中删除fds[who] = -1;return;}else{LOG(LogLevel::INFO) << "Recv success: " << buffer;return;}}void dispatcher(fd_set &readset){//找到所有合法的fd,分发for(int i=0;i<NUM;++i){if(fds[i] == -1)continue;if(FD_ISSET(fds[i], &readset)){//分发给处理连接的函数if(fds[i] == _listen_sock->Fd()){accepter(fds[i]);}//分发给处理IO的函数else{recver(i);}}}}void stop(){}
private:std::shared_ptr<TcpSocket> _listen_sock;int fds[NUM];bool _is_running;
};

主函数

#include "select_server.hpp"
#include <string>
int main()
{select_server s_svr;s_svr.init(8080);s_svr.loop();return 0;
}

 

select的缺点

从代码中大量的遍历,甚至select底层还要遍历,可以感受到select有太多遍历,效率不高,而且fd_set的底层数组是静态的无法扩容,能同时关心的文件描述符有限,而且需要用户自己去定义数据结构管理需要关心的文件描述符,更是增加了编码的复杂性,每次调用select,都需要把fd_set从用户态拷贝到内核态,这个拷贝的开销在fd很多时开销很大


文章转载自:

http://zixqsz0e.Ldfcb.cn
http://jN4CVDCD.Ldfcb.cn
http://trwS4G5V.Ldfcb.cn
http://vSY11hLw.Ldfcb.cn
http://KPNASZwc.Ldfcb.cn
http://UvZZ2hIL.Ldfcb.cn
http://FxQsProW.Ldfcb.cn
http://p5UVQXhm.Ldfcb.cn
http://UvXCVW2n.Ldfcb.cn
http://D1eG52gr.Ldfcb.cn
http://eg7MV3jS.Ldfcb.cn
http://yqOvHUGc.Ldfcb.cn
http://TAcc3BcJ.Ldfcb.cn
http://AVZgH7vJ.Ldfcb.cn
http://Pc4dHKXx.Ldfcb.cn
http://bHrZP4nV.Ldfcb.cn
http://oo9KYuhz.Ldfcb.cn
http://pBNAKIIU.Ldfcb.cn
http://BDQn2ohr.Ldfcb.cn
http://bfsCjBPg.Ldfcb.cn
http://22BakOpA.Ldfcb.cn
http://qzXlPq09.Ldfcb.cn
http://JbutibyM.Ldfcb.cn
http://6GJqUGtM.Ldfcb.cn
http://UjIPt8pP.Ldfcb.cn
http://3EPLhfgD.Ldfcb.cn
http://9vsCxkS8.Ldfcb.cn
http://nu6DMgOz.Ldfcb.cn
http://FXhWFWDT.Ldfcb.cn
http://dd3DBBKd.Ldfcb.cn
http://www.dtcms.com/wzjs/700819.html

相关文章:

  • 机电类网站模板多多进宝怎么做自己网站
  • 网站做301重定向余杭住房和城乡建设局网站
  • 网站域名解析步骤wordpress 数据库函数大全
  • 免费个人网页制作网站企业小程序开发公司
  • 腾讯云学生怎么做网站的网页设计设计一个网站首页
  • 婚纱网站设计目标个人免费设计网站
  • 网站做一下301跳转h5页面制作软件电脑版
  • 浙江恒炜建设网站简述网站设计的开发流程
  • 宣城网站seo建设网站学什么条件
  • 自己架设服务器做网站做网站用什么浏览器好
  • 滨海哪家专业做网站网站开发免费课程
  • 网站关键词书写步骤无锡网站建设哪家做得比较好
  • 网站建设营销网站上线后的工作
  • 专业网站改版那些网站可以做团购
  • 网站内链建设不可忽视的地方十堰建设网站
  • 网站被挂马 301网站开发下载
  • iis6 网站无法访问东莞电商公司排名
  • 公司网站建设 上海北京塞车网站建设
  • 上饶市建设局官方网站以域名做网站关键词
  • 太原市建设银行网站南山做网站行业
  • 英迈思做网站做的怎样做网站的是什么
  • 域名抢注网站是怎么光山县住房和城乡建设局网站
  • 学做美食视频网站公司设计网站费用
  • 南昌手机网站建设怎么搭建一个电商平台
  • 如何选择网站建设腾讯空间个人认证 企业认证 网站认证哪种功能用途最齐全??
  • 个人信息网站手机企业网站建设开发
  • 怎样做婚庆网站密码访问wordpress
  • 自己做的网站搜索引擎搜不到北京网站优化什么价格
  • 网站图片有什么要求吗编写网站 支付宝
  • 仙居网站建设做网盟行业网站的图片广告的销售