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

建立网站信息内容建设管理规范网站已备案下一步怎么做

建立网站信息内容建设管理规范,网站已备案下一步怎么做,dw做网站小技巧,一般的学校网站怎么做目录 IO的基本概念 什么是高效的IO#xff1f; 五种IO模型 阻塞IO 非阻塞IO 信号驱动IO IO多路转接 异步IO 同步通信VS异步通信#xff08;synchronous communication / asynchronous communication#xff09; 同步通信VS同步与互斥 阻塞VS非阻塞 其他高级IO … 目录 IO的基本概念 什么是高效的IO 五种IO模型 阻塞IO 非阻塞IO 信号驱动IO IO多路转接 异步IO 同步通信VS异步通信synchronous communication / asynchronous communication 同步通信VS同步与互斥 阻塞VS非阻塞 其他高级IO 阻塞IO 非阻塞IO  实现函数 SetNoBlock 以非阻塞轮询释放读取标准输入 I/O多路转接之select 初识 select  关于 fd_set 结构 ​编辑 关于 timeval 结构 socket 就绪条件  socket 基本工作流程 select 服务器 selectServer 类 timeout 时间测试 事件处理  select 的优缺点 select可监控的fd个数 IO的基本概念 I/OInput / output就是输入和输出在冯诺依曼体系中将数据从输入设备拷贝到内存叫做输入将数据从内存拷贝到输出设备叫做输出。 · 对文件进行的读写操作本质就是一种IO文件IO对应的外设就是磁盘。 · 对网络进行的读写操作本质也就是一种IO网络IO对应的外设就是网卡。 什么是高效的IO IO主要分为两个步骤 · 第一步是等就是等待IO条件的就绪。 · 第二步就是拷贝就是IO条件就绪后将数据拷贝到内存或者外设中。 所以 IO 等 数据拷贝但是实际中 “等” 消耗的时间往往比 “拷贝” 消耗的时间多因此让 IO 变得更高效就是要减少 “等” 的时间。 五种IO模型 阻塞IO 阻塞IO就是内核将数据准备好之前系统调用会一直等待所有套接字默认都是阻塞方式也是最常见的IO模型 · 在 recvfrom 函数等待数据就绪期间在用户看来该进程或者线程被阻塞住了本质是操作系统将该进程或者线程的状态设置为了某种非 R 状态然后放入等待队列当中当数据就绪后操作系统再将其从等待队列中唤醒然后该进程或者线程再将数据从内核拷贝到用户空间。 · 阻塞IO在 “等” “数据拷贝” 期间都不会返回在用户看来就像是阻塞住了。 非阻塞IO 如果内核还未将数据准备好系统调用仍然会直接返回 并且返回EWOULDBLOCK错误码 非阻塞IO往往需要程序猿自己循环反复尝试读写文件描述符这个过程称为轮询这对CPU来说是较大的浪费一般只有特定场景下使用。  · 每次调用 recvfrom 函数读取数据时就算底层数据没有就绪recvfrom 函数也会立马返回错误信息后续还需要继续不断调用 recvfrom 函数直到底层有数据就绪在用户看来该进程或者线程就没有被阻塞住称为非阻塞IO。 阻塞IO 和 非阻塞IO 区别 阻塞IO当数据没有就绪时后续检测数据是否就绪工作是操作系统发起的。 非阻塞IO当数据没有就绪时后续检测数据是否就绪工作是用户发起的。 信号驱动IO 内核将数据准备好的时候使用SIGIO信号通知应用程序进行IO操作。 当底层数据就绪的时候会向当前进程或者线程发送SIGIO信号因此可以通过signal或者sigaction函数将SIGIO的信号处理程序自定义为需要进行的IO操作当底层数据就绪时就会自动执行对应的IO操作。 信号的产生是异步的但信号驱动IO是同步IO的一种 · 信号的产生是异步的因为信号在任何时刻都可能会产生。 · 信号驱动IO是同步IO的一种当底层数据就绪时当前进程或者线程需要停下来正在做的事情转而进行数据的拷贝操作因此当前进程或者线程仍然需要参加IO的过程。 · 一个IO过程是同步还是异步看当前进程或者线程是否参与到IO的过程中参与了是同步IO没有参与就是异步IO。 IO多路转接 也叫做IO多路复用最核心在与能够同时等待多个文件描述符的就绪状态。 IO多路转接思想 · 使用 recvfrom 等接口需要进行等可以将所有的 “等” 的工作交给多路转接接口selectpollepoll · 多路转接接口一次 “等” 多个文件描述符因此能够将 “等” 的时间进行重叠当数据就绪后再调用对应的 recvfrom 等函数进行数据的拷贝此时这些函数就能直接进行拷贝而不需要进行 “等” 操作。 异步IO 由内核在数据拷贝完成时通知应用程序而信号驱动是告诉应用程序何时可以开始拷贝数据。 · 进行异步IO需要调用一些异步IO的接口异步IO接口调用后立马进行返回。 · 当IO完成后操作系统会通知应用程序因此进行异步IO的进程或者线程并不参与IO的所有细节。 同步通信VS异步通信synchronous communication / asynchronous communication 同步和异步关注的是消息的通信机制 · 所谓同步就是在发出一个调用时在没有得到结果之前该调用就不返回但是一旦调用返回就得到了返回值了换句话来说就是由调用者主动等待这个调用的结果。 · 异步则是相反调用在发出之后这个调用就直接返回了所以没有返回结果换句话来说当一个异步过程调用发出后调用者不会立即得到结果而是最调用发出后被调用者通过状态通知来通知调用者或通过回调函数处理这个调用。 同步通信VS同步与互斥 · 进程 / 线程同步在保证数据安全的前提下让进程 / 线程 能够按照某种特定的顺序访问临界资源从而有效避免饥饿问题谈论的是进程 / 线程间的一种工作关系。 · 而同步 IO进程 / 线程 与操作系统之间的关系谈论的是 进程 / 线程 是否需要主动参与IO过程。 阻塞VS非阻塞 阻塞和非阻塞关注的是程序在等待调用结果信息返回值的状态 · 阻塞调用是指调用结果返回之前当前线程会被挂起调用线程只有在得到结果之后才会返回。 · 非阻塞调用指在不能立即得到结果之前该调用不会阻塞当前线程。 其他高级IO 非阻塞IO记录锁系统V流机制I/O多路转接I/O多路复用readv和writev函数以及存储映射IOmmap。 阻塞IO 使用read函数从标准输入当中读取数据 #include iostream #include unistd.h int main() {// 阻塞IOchar buffer[1024];while (true){printf(Please#: );fflush(stdout);ssize_t n read(0, buffer, sizeof(buffer) - 1);if (n 0){buffer[n - 1] 0;std::cout echo#: buffer std::endl;}else if (n 0){std::cout me too quit! std::endl;break;}else{std::cout read error std::endl;break;}} } 将程序运行如果不进行输入操作此时该进程就会阻塞住根本原因是底层数据没有进行就绪无数据此时read函数在进行阻塞等待 此时进行输入操作read函数检测到底层数据就绪时立马将数据读取从内核拷贝到buffer数组中进而将数据进行输出 非阻塞IO  打开文件时默认都是以阻塞的方式打开的如果要以非阻塞的方式打开某个文件需要在使用open函数打开文件时需要携带 O_NONBLOCK或者 O_NDELAY 选项此时就能够以非阻塞的方式打开文件。 如果要将已经打开的某个文件或者套接字设置为非阻塞需要用到 fcntl 函数。 • fd已经打开的文件描述符 • cmd需要进行的操作 • ... 可变参数传入的cmd不同后面追加的参数也不同。 fcntl 函数有5种功能 • 复制一个现有的描述符cmd F_DUPFD • 获得 / 设置文件描述符标记cmd F_GETFD 或 F_SETFD • 获得 / 设置文件状态标记cmd F_GETFL 或 F_SETFL • 获得 / 设置异步 I/O 所有权cmd F_GETOWN 或 F_SETOWN • 获得 / 设置记录锁cmd F_GETLKF_SETLK 或 F_SETLKW 如果函数调用成功返回值取决于具体的进行对操作调用失败返回 -1错误码被设置。 实现函数 SetNoBlock 基于 fcntl实现一个SetNoBlock函数将文件描述符设置为非阻塞 void SetNonBlock(int fd) {// 将fd设置为非阻塞int fl fcntl(fd, F_GETFL); // 获取一下fd的状态(GETFD 获取值)if (fl 0){std::cerr fcntl: strerror(errno) std::endl;return;}fcntl(fd, F_SETFL, fl | O_NONBLOCK); }• 使用 F_GETFL 将当前的文件描述符的属性取出来这是一个位图 • 再使用 F_SETFL 将文件描述符设置回去设置回去的同时加上一个 O_NONBLOCK参数。 以非阻塞轮询释放读取标准输入 在调用read函数之前先调用SetNonBlock函数将0号文件描述符设置为非阻塞 #include util.hpp #include cstdlib #include vector #include functional using namespace std;using func_t functionvoid();#define INIT(v) \do \{ \v.push_back(printlog); \v.push_back(installlog); \} while (0);#define EXITLOG(v) \do \{ \for (const auto e : v) \{ \e(); \} \} while (0);void printlog() {std::cout this is a print log! std::endl; }void installlog() {std::cout this is a install log! std::endl; }int main() {// 非阻塞式IO 在非阻塞期间能做自己的事情SetNonBlock(0); // 将fd设置为非阻塞vectorfunc_t vf;INIT(vf);// 阻塞IOchar buffer[1024];while (true){// printf(Please#: );// fflush(stdout);ssize_t n read(0, buffer, sizeof(buffer) - 1);if (n 0){buffer[n - 1] 0;std::cout echo#: buffer std::endl;}else if (n 0){std::cout me too quit! std::endl;break;}else{// 读取出现错误 显示资源未就绪 错误根据错误码分析是否是真的read错误还是无资源// std::cout strerror: strerror(errno) errno: errno std::endl;// break;if(errno EAGAIN){//非阻塞cout 此时只是无数据没有错误 endl;EXITLOG(vf);}else if(errno EINTR){cout接受到了阻断信号,也不是read错误!endl;continue;}else{cout strerror: strerror(errno) errno: errno endl;break;}}sleep(1);}return 0; } 此时read 函数以非阻塞方式读取标准输入时底层数据不就绪read 函数就会立即返回以错误的形式错误码被设置为 EAGAIN 或 EWOULDBLOCK 在以非阻塞方式进行读取时在read 函数返回值是 -1 的情况下还需要根据错误码进一步判断如果错误码是 EAGAIN 或者 EWOULDBLOCK说明此时底层数据还没有就绪还需要进行轮询检测read 函数在读取到数据之前可能会被其他信号中断也会以错误的形式返回错误码被设置为 EINTR此时应该重新执行 read 函数进行数据读取 运行程序此时没有输入数据程序就会不断调用 read 函数检测底层数据是否就绪 当进行输入操作后read 函数就会轮询检测read 函数立马将数据读取从内核拷贝到 buffer 数组中并进行输出 I/O多路转接之select 初识 select  select 的函数原型 系统提供 select 函数来实现多路复用输入 / 输出模型 • select 系统调用是用来让程序监视多个文件描述符的状态变化的。 • 程序会停在 select 这里等待直到被监视在文件描述符有一个或者多个发生了状态改变。 参数介绍 • nfds需要监视的文件描述符当中最大的文件描述符值 1。 • readfds输入输出型参数调用时用户告知内核需要检视哪些文件描述符的读事件是否就绪返回时内核告知用户哪些文件描述符的读事件已经就绪。 • writefds输入输出型参数调用时用户告知内核需要检视哪些文件描述符的读事件是否就绪返回时内核告知用户哪些文件描述符的写事件已经就绪。 • exceptfds输入输出型参数调用时用户告知内核需要检视哪些文件描述符的读事件是否就绪返回时内核告知用户哪些文件描述符的异常事件已经就绪。 • timeout输入输出型参数调用时由用户设置 select 的等待时间返回时表示 timeout 的剩余时间。 参数 timeout 的取值 • NULL则表示 select 函数没有 timeoutselect 将一直被阻塞直到某个文件描述符上发生了事件 • 0仅检测描述符集合的状态然后立即返回并不等待外部时间的发生。 • 特定的时间值如果指定的时间段里面没有事件发生select 将超时返回。 返回值说明 • 如果函数调用成功则返回有事件就绪的文件描述符个数调用失败返回 -1错误码被设置。 • timeout时间耗尽则返回0。 关于 fd_set 结构 本质是一个位图结构用位图中对应的位置来表示要监视的文件描述符 调用 select 函数之前需要定义fd_set对应的文件描述符集然后将需要监视的文件描述符添加到文件描述符集合当中系统提供了一组操作 fd_set 的接口方便操作位图 关于 timeval 结构 select 的最后一个参数 timeout是一个指向 timeval 结构的指针timeval 结构用于描述一段时间长度该结构中有两个成员变量tv_sec 表示秒tv_usec 表示微秒。 socket 就绪条件  读就绪 • socket 内核中接收缓冲区中的字节数大于等于低水位标记 SO_RECVLOWAT此时可以无阻塞的读该文件描述符并且返回值大于0 • socket TCP通信中对端关闭连接此时对该socket读则返回0 • 监听的socket上有新的连接请求 • socket 上有未处理的错误 写就绪 • socket 内核中发送缓冲区中的可用字节数发送缓冲区的空闲位置大小大于等于水位标记 SO_SNDLOWAT此时可以无阻塞的写并且返回值大于0 • socket 的写操作被关闭close 或者 shutdown对一个写操作被关闭的 socket 进行写操作会触发SIGPIPE信号 • socket 使用非阻塞 connect 连接成功或失败之后 • socket 上有未读取的错误 异常就绪 • socket 上收到带外数据带外数据和TCP的紧急模式相关TCP报头当中的URG标志位和16位紧急指针搭配使用就能发送和接收带外数据 socket 基本工作流程 实现一个简单的 select 服务器该服务器做的内容就是读取客户端发来的数据进行输出打印即可 • 初始化服务器套接字的创建绑定端口号和IP地址等设置监听状态 • 定义一个 _fdarray 数组用于保存监听套接字和已经与客户端建立好连接的套接字一开始只有监听套接字就绪先把监听套接字添加到 _fdarray 数组中 • 服务器开始运行一直轮询调用 select 函数检测读事件是否就绪有事件就绪了就执行对应的操作 • 在每次调用 select 函数之前需要定义一个文件描述符集 rfds把 _fdarray 中的文件描述符依次添加到集合中让 select 函数检测这些文件描述符中哪些文件描述符的读事件是否就绪。 • 当 select 检测到数据就绪时就会将读事件就绪的文件描述符设置进入到 rfds 中这个参数是一个输入输出型参数就可以知道哪些文件描述符就绪了并对这些文件描述符进行对应的操作 • 如果就绪的是监听套接字就调用 accept 函数从底层全连接队列获取已经建立好的连接并且将对应的套接字添加到 _fdarray 数组中 • 如果就绪的是与客户端建立连接的套接字就调用 read 函数将客户端发送到数据进行接收并进行打印输出 • 服务器与客户端建立连接的套接字读事件就绪也有可能是因为客户端将连接的套接字关闭了此时服务器应该调用 close 关闭该套接字并将该套接字从 _fdarray 数组中移除 细节 1、select 函数除了 nfds之外其他都是输入输出型参数当 select 返回时这些参数的值都已经被修改了每次调用时 select 函数需要对参数进行重新设置timeout 也一样需要设置 2、select 需要传入的被监视的文件描述符中最大描述符值 1在遍历 _fdarray 时需要记录最大文件描述符的值。 select 服务器 socket 类 编写一个 Socket 类对套接字的接口进行一定程度的封装为了外部通过作用域直接调用Socket 类当中的封装函数将这些接口函数定义成为静态成员函数 // 进行封装 TCP socket 编写 #pragma once#include iostream #include string #include cstring #include unistd.h #include strings.h #include sys/types.h #include sys/wait.h #include sys/socket.h #include netinet/in.h #include arpa/inet.h#include logMessage.hpp #include error.hpp#define gbacklog 5class Sock { public:static int Socket(){// 1.创建套接字 面向字节流int listensock socket(AF_INET, SOCK_STREAM, 0);if (listensock 0){logMessage(FATAL, Create Socket Fail!);exit(SOCKET_ERR);}logMessage(NORMAL, Create Socket Success!);// 处理一下 Time_Wait 导致无法绑定端口号问题int opt 1;setsockopt(listensock, SOL_SOCKET, SO_REUSEADDR, opt, sizeof(opt));return listensock;}static void Bind(int sock, int port){// 2.bindstruct sockaddr_in peer;bzero(peer, sizeof(peer));peer.sin_addr.s_addr INADDR_ANY; // IP地址绑定任意的peer.sin_family AF_INET;peer.sin_port htons(port);if (bind(sock, (struct sockaddr *)peer, sizeof(peer)) 0){logMessage(FATAL, Bind Socket Fail!);exit(BIND_ERR);}logMessage(NORMAL, Bind Socket Success!);}static void Listen(int sock){// 3.Socket 设置为监听状态if (listen(sock, gbacklog) 0){// 设置失败logMessage(FATAL, Listen Socket Fail!);exit(LISTEN_ERR);}logMessage(NORMAL, Listen Socket Success!);}// 获取新连接static int Accpet(int listensock, uint16_t *clientPort, std::string *clientIP){struct sockaddr_in peer;socklen_t len sizeof(peer);int sock accept(listensock, (struct sockaddr *)peer, len);if (sock 0){logMessage(FATAL, Accept Socket Fail!);exit(ACCEPT_ERR);}else{logMessage(NORMAL, Accpet Socket Success,get a new sock: %d, sock);*clientPort ntohs(peer.sin_port); // 网络转主机*clientIP inet_ntoa(peer.sin_addr); // 网络转主机再转字符串}return sock;} }; selectServer 类 所编写的服务器在绑定时不需要显示绑定IP地址直接设置为 INADDR_ANY 即可在类的成员变量中只需要包含监听套接字和端口号即可。 运行服务器 select 服务器要做的是不断调用select 函数当有事件就绪时做出处理动作 • 需要将数组中所有位置的值初始化为无效并将监听套接字添加到数组的第一个位置 • select 函数返回后如果返回0说明 timeout 时间耗尽直接进行下一次的 select 调用即可返回 -1根据返回的错误码来进一步判断是否需要下一次继续调用 select 函数返回值大于0调用成功已经有文件描述符的读事件就绪对就绪事件进一步处理 #pragma once #include iostream #include string #include unistd.h #include sys/time.h #include sys/types.h #include functional#include sock.hppnamespace Server {using func_t std::functionstd::string(const std::string );const uint16_t defaultPort 8080;const int fdnum sizeof(fd_set) * 8;const int defaultnum -1;class SelectServer{public:SelectServer(func_t f, int port): _func(f), _listensock(-1), _port(port){}~SelectServer(){if (_listensock){close(_listensock);}if (_fdarray){delete[] _fdarray;}}void InitServer(){_listensock Sock::Socket();Sock::Bind(_listensock, _port);Sock::Listen(_listensock);_fdarray new int[fdnum];for (int i 0; i fdnum; i){_fdarray[i] defaultnum;}_fdarray[0] _listensock;}void Start(){// 等 处理数据 select返回的是fd的个数for (;;){fd_set rfd;// 初始化rfdFD_ZERO(rfd);int maxfd _fdarray[0]; // 最大fd数 1for (int i 0; i fdnum; i){if (_fdarray[i] defaultnum){continue;}// 将这个fd 设置进入rfd中FD_SET(_fdarray[i], rfd);if (_fdarray[i] maxfd){maxfd _fdarray[i];}}logMessage(NORMAL, max fd is: %d\n, maxfd);// 非阻塞 每隔一秒询问一下//struct timeval _timeval {1, 0};// int n select(maxfd 1, rfd, nullptr, nullptr, _timeval);int n select(maxfd 1, rfd, nullptr, nullptr, nullptr);switch (n){case 0:// 超时logMessage(NORMAL, time out ...);break;case -1:logMessage(WARNING, select errno code: %d, select errno message: %s, errno, strerror(errno));break;default:// 走到这里说明有fd就绪了需要进行处理但是只有 listensock 就绪logMessage(NORMAL, have event ready!\n);// 进行业务逻辑处理Handerevent(rfd);break;}}}private:int _port;int _listensock;int *_fdarray; // 维护的accpet的fd数组func_t _func;}; } timeout 时间测试 在运行服务器时需要实例化一个对象对select 服务器进行初始化并调用 Start 函数运行服务器 #include iostream #include string #include memory#include error.hpp #include selectServer.hppvoid Usage(std::string arg) {std::cout \n Usage: \n\t arg port \n\t std::endl; }// ./main 8080 int main(int argc, char *argv[]) {if (argc ! 2){Usage(argv[0]);}std::unique_ptrServer::SelectServer us(new Server::SelectServer(transmition, atoi(argv[1])));us-InitServer();us-Start();return 0; } 此时的服务器 select 函数将 timeout 设置为了 nullptr因此select 函数调用时会阻塞等待服务器在第一次调用 select 时只监视监听套接字listensock运行服务器后客户端没有请求发送过来请求连接读事件就不会就绪服务器第一次调用 select 函数中就会进行阻塞等待 使用 telnet 工具向服务器发起连接请求此时 select 函数会立马检测到监听套接字的读事件就绪然后对套接字做出对应的处理逻辑 如果此时将timeout的值设置为0select 函数调用后就会进行非阻塞等待无论被监视的文件描述符是否就绪检测后都会立马返回如果有事件就绪select 函数的返回值就会大于0没有事件就绪返回值就会等于0 struct timeval _timeval {0, 0};int n select(maxfd 1, rfd, nullptr, nullptr, _timeval);switch (n){case 0:// 超时logMessage(NORMAL, time out ...);break;case -1:logMessage(WARNING, select errno code: %d, select errno message: %s, errno, strerror(errno));break;default:// 走到这里说明有fd就绪了需要进行处理但是只有 listensock 就绪logMessage(NORMAL, have event ready!\n);// 进行业务逻辑处理Handerevent(rfd);break;} 此时如果没有客户端发送连接请求select 函数就会一致进行轮询检测每次检测的读事件都不就绪返回结果都是0就会造成 time out ... 现象。  如果将 timeout 时间设置为特定的时间比如这里设置为5s那么select 函数调用后5秒内会进行阻塞等待5秒后依旧没有读事件就绪就会超时返回 struct timeval _timeval {5, 0}; 运行服务器此时无客户端发送到连接请求select 函数调用5秒后都会超时返回 如果在5秒内有读事件就绪那么 timeout 就会返回剩余的时间所以在每次调用select 函数时都需要对 timeout 时间重新设置。 事件处理  当select 检测到有文件描述符就绪时并成功返回后就需要对就绪事件进行处理 • 需要遍历整个 _fdarray 数组当中的文件描述符依次判断各个文件描述符的都事件是否就绪如果就绪进行处理 • 如果文件描述符就绪后还需要判断该文件描述符是否是监听套接字如果是监听套接字就绪就需要调用 accept 函数将底层的连接获取上来并添加到 _fdarray 数组当中在下一次调用select 函数之前将 _fdarray 中的文件描述符设置进入到 rfds 中 • 如果是客户端建立的连接对应的读事件就绪就需要调用 read 函数读取客户端发来的数据如果读取成功就将读到的数据进行在服务器端打印如果读取失败或者客户端关闭了连接那么服务器就调用close 函数关闭对应的连接并且将对应的文件描述符从 _fdarray 中移除 void Accpeter(int listensock){// 获取新连接后直接添加进入到 _fdarray 数组中logMessage(NORMAL, Accpeter begin ...\n);uint16_t clientPort 0;std::string clientIP;int sock Sock::Accpet(listensock, clientPort, clientIP);if (sock 0){return;}int i 0;for (; i fdnum; i){if (_fdarray[i] ! defaultnum){continue;}else{break;}}// 找到位置if (i fdnum){// 说明已经满了logMessage(WARNING, server is full,please wait ...\n);}else{_fdarray[i] sock;}// 进行打印Print();logMessage(NORMAL, Accpeter end ...\n);}void Recver(int sock, int i){// 通过sock这个fd进行接受数据logMessage(NORMAL, Recver begin ...\n);char buffer[1024];ssize_t n recv(sock, buffer, sizeof(buffer) - 1, 0); // 这里读取不会阻塞只有sock就绪了才进来if (n 0){buffer[n - 1] 0;logMessage(NORMAL, client# %s, buffer);}else if (n 0){// 读取错误close(sock);_fdarray[i] defaultnum;logMessage(WARNING, recv error# %s, strerror(errno));return;}else // 0{// client 退出了close(sock);_fdarray[i] defaultnum;logMessage(NORMAL, client quit,me too ...);return;}// 此时数据都在buffer当中处理 requeststd::string response _func(buffer);write(sock, response.c_str(), response.size());logMessage(NORMAL, Recver end ...\n);}// 处理逻辑void Handerevent(fd_set rfd){// 判断是listensock还是普通sock的for (int i 0; i fdnum; i){if (_fdarray[i] defaultnum){continue; // 后面需要进行置空不能break}if (_fdarray[i] _listensock FD_ISSET(_fdarray[i], rfd)){// 需要进行accpetAccpeter(_fdarray[i]);}else if (FD_ISSET(_fdarray[i], rfd)){// 其他fd 而且就绪Recver(_fdarray[i], i);}else{}}} select 的优缺点 优点 • 可以同时等待多个文件描述符并且只负责等待实际的IO操作由acceptreadwrite 函数来完成这些接口在进行IO操作时不会被阻塞。 • select 同时等待多个文件描述符因此可以将“等”的事件重叠提高IO的效率。 缺点 • 每次调用select都需要手动设置fd集合从接口使用角度来说非常不方便 • 每次调用select都需要把fd集合从用户拷贝到内核态这个开销在fd很多时会很大 • 同时每次调用select都需要在内核遍历传递进来的所有fd这个开销在fd很多时也很大 • select支持的文件描述符数量太小 select可监控的fd个数 fd_set结构本质是一个位图用每一个比特位来标记一个文件描述符select可监控的文件描述符个数取决于fd_set类型的比特位个数通过计算sizeof(fd_set)* 8 可得总共1024个字节说明可监控的文件描述符个数为1024在初始化 _fdarray 数组时需要将数组大小定义为 1024即可 const int fdnum sizeof(fd_set) * 8;
http://www.pierceye.com/news/688269/

相关文章:

  • 福建省建设环卫协会网站自动的小企业网站建设
  • 深圳关键词seo北京网络优化推广公司
  • 旅游网站建设课程设计报告内部优惠券网站建站
  • 郑州网站优化汉狮网络苏州互联网公司集中在哪里
  • 烟台网站建设精通臻动传媒ui培训设计学校
  • 网站推荐你了解我意思吧深圳响应式设计企业网站
  • 网站后期增加产品东平网页设计
  • 免费网站模板的制作方法石台做网站
  • 温州建设网站公司哪家好游戏外包公司要不要去
  • 动力无限西安网站建设wordpress图片到本地
  • 重庆微信营销网站建设seo快照推广
  • dedecms小说网站模板如何以目录形式访问网站
  • 有哪些可以做网站的平台怎样把录的视频做一下传到网站
  • 网站域名如何续费福建建筑人才服务中心
  • 站长平台怎么添加网站网站中文名注册
  • 唐四薪php网站开发答案想制作一个网站要多少钱
  • ppt网站建设答案东台网页定制
  • 做网站 侵权如何制作手机版网站
  • 代发网站建设app网站软件
  • 家居企业网站建设如何国家企业信息公示系统全国
  • 网站平台如何推广wordpress登录页面显示ip
  • 如何做网站百度排名优化推广的目的是什么
  • 重庆忠县网站建设公司哪家专业芷江建设局的工作人员网站
  • 戴尔电脑网站建设方案范文室内设计方案图
  • 餐厅网站建设策划方案网站建设存在的具体问题
  • 竞价页面网站做优化广告商对接平台
  • 网站后台如何修改密码wordpress调整页面布局
  • 东莞热点网站建设莱州人才网
  • 线上渠道推广网站的优化哪个好
  • 群晖可以做网站服务器微信朋友圈怎么发链接那种网页怎么制作