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

长春代做网站电脑培训速成班多少钱

长春代做网站,电脑培训速成班多少钱,怎样让网站的排名靠前,盐山建网站文章目录 poll模型pollfd结构体nfds_t的定义 一个简单的poll服务器总结 poll模型 poll模型和select模型类似&#xff0c;都是在指定时间内轮询一定数量的文件描述符&#xff0c;以测试其中是否有就绪者&#xff0c;需要使用头文件poll.h&#xff1a; #include <poll.h>…

文章目录

    • poll模型
      • pollfd结构体
      • nfds_t的定义
    • 一个简单的poll服务器
    • 总结

poll模型

poll模型和select模型类似,都是在指定时间内轮询一定数量的文件描述符,以测试其中是否有就绪者,需要使用头文件poll.h

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

在select中使用的是fd_set结构体,而在此处的是pollfd和nfds_t,timeout的作用和select的一样,用于指定poll的超时值:当timeout的值为-1时,poll调用将会永远阻塞,直到某个事件发生;当timeout为0时,poll调用将立即返回
poll的返回值也和select一致,表示就绪文件描述符的总数。

pollfd结构体

struct pollfd{int fd; // 文件描述符short int events; // 注册的事件short int revents; // 实际发生的事件,由内核填充
};
  • fd指定文件描述符
  • events成员告诉poll监听fd上的哪些事件,它是一系列事件的按位或
  • revents成员由内核修改,以通知应用程序fd上实际发生了哪些事件

poll支持以下事件类型:

事件描述是否可作为输入是否可作为输出
POLLIN数据(包括普通数据和优先数据)可读
POLLRNDORM普通数据可读
POLLRDBAND优先级带数据可读
POLLPRI高优先级数据可读,比如TCP带外数据
POLLOUT数据(包括普通数据和优先数据)可写
POLLWRNORM普通数据可写
POLLWRBAND优先级带数据可写
POLLRDHUPTCP连接被对方关闭,或者对方关闭了写操作。它由GNU引入
POLLERR错误
POLLHUP挂起。比如管道的写端被关闭后,读端描述符上将收到POLLHUP事件
POLLNVAL文件描述符没有打开

在表中提到了很多事件,但是Linux中没有完全支持它们
通常,应用程序需要根据recv调用的返回值来区分socket上接受到的是有效数据还是对方关闭连接的请求,并做相应的处理。

不过,自Linux内核2.6.17开始,GNU为poll系统调用增加了一个POLLRDHUP事件,它在socket上接收到对方关闭连接的请求后触发。这为我们区分recv接受到的数据是有效数据还是对方关闭连接的请求提供了一种更简单的方式。
但使用POLLRDHUP事件时,我们需要在代码最开始处定义_GNU_SOURCE

nfds_t的定义

typedef unsigned long int nfds_t;

该参数用来指定被监听事件集合fds的大小

一个简单的poll服务器

这个服务器是个简单的echo服务器:

#include <iostream>
#include <vector>
#include <sys/socket.h>
#include <poll.h>
#include <algorithm>
#include <arpa/inet.h>
#include <assert.h>
#include <vector>
#include <unistd.h>using namespace std;int main(int argc, char* argv[]){if(argc != 3){cerr << "格式为 ip port" << endl;return 1;}int serverSocket, clientSocket;/*这个头文件在in.h中(实际上我们调用的是inet/in.h而inet/in.h被包含在头文件arpa/inet。h中了*/struct sockaddr_in serverAddr{}, clientAddr{};socklen_t clientAddrLen;// 创建监听套接字serverSocket = socket(AF_INET, SOCK_STREAM, 0);assert(serverSocket != -1);serverAddr.sin_family = AF_INET;/*htons的英文意思是host to network shrot用于将16位无符号短整型(port)的主机字节序转换为网络字节序*/serverAddr.sin_port = htons(stoi(argv[2])); /*在调用 inet_pton 函数时,需要将 &(address.sin_addr) 作为参数传递,而不是 &(address.sin_addr.s_addr)struct sockaddr_in 结构体中的 sin_addr 字段是一个 struct in_addr 类型的结构体它包含了 IP 地址的二进制表示形式。in_addr 结构体中的 s_addr 字段实际上就是一个无符号整数类型(uint32_t)用来存储 IP 地址的二进制形式。*/inet_pton(AF_INET, argv[1], &(serverAddr.sin_addr));// 绑定套接字到地址和端口int ret = bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));assert(ret != -1);ret = listen(serverSocket, 5);assert(ret != -1);// 监听的文件描述符队列/*创建一个pollfd类型的空向量并且将之前创建的serverSocket加入到其中进行监听POLLIN是我们所监视的事件类型,这点笔记中有写为什么需要监视serverSocket?答:这是为了实现服务器的异步IO,通过监视serverSocket及时检测到下面两种情况:1. 当有新的客户端连接请求到达时,我们希望能够立即进行处理。通过监视serverSocket上的POLLIN事件,可以检测到是否有客户端尝试建立连接2. 当serverSocket上出现其他错误情况(如连接断开或发生错误)时,我们也希望能及时进行处理通过监视serverSocket上的激长时间,如POLLHUP或POLLERR,可以检测到这些错误情况*/vector<pollfd> fds;fds.push_back({serverSocket, POLLIN});while(true){int numRead = poll(fds.data(), fds.size(), -1);if(numRead < 0){cerr << "poll error";return 1;}// for(auto &fd : fds){/*确保有新的连接但是不是很理解为什么是一直监听serverSocket*/if(fd.fd == serverSocket && fd.revents & POLLIN){// 有新连接clientAddrLen = sizeof(clientAddr);clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddr, &clientAddrLen);if(clientSocket < 0){cerr << "Failed to accepted connection" << endl;return 1;}else{cout << "New connection from:" << inet_ntoa(clientAddr.sin_addr) << endl;fds.push_back({clientSocket, POLLIN});}}else if(fd.revents & POLLIN){// 需要读取信息// 此时的不是监听socket,而是客户端的连接socketchar buffer[1024];ssize_t bytesRead = recv(fd.fd, buffer, sizeof(buffer), 0);if(bytesRead <= 0){if(bytesRead < 0){cerr << "Error reading from client." << endl;}else{cout << "Connection clost by client." << endl;}close(fd.fd);// 这个remove_if()不是很熟fds.erase(remove_if(fds.begin(), fds.end(),[&](const pollfd& pfd){ return pfd.fd == fd.fd; }),fds.end());}else{// 处理数据cout << "Received data: " << string(buffer, bytesRead) << endl;// 将收到的数据回发给客户端send(fd.fd, buffer, bytesRead, 0);}}}}// 关闭监听套接字close(serverSocket);return 0;
}

总结

学到这里我就发现:想要真正去理解Linux网络编程,还是要懂Linux内核,比如:套接字和文件描述符的联系?要去了解下select和poll的工作原理,这样才能理解程序为何这么编写。

http://www.dt0577.cn/news/4038.html

相关文章:

  • 网站推广seo招聘微博推广方案
  • django网站开发视频教程下载网址搜索域名查询
  • 中山网站建设设计浏览器如何推广自己网站
  • 网站建设建议口碑营销有哪些
  • uc网站怎么做济南竞价托管公司
  • 一站式企业服务平台是什么磁力多多
  • python网站开发视频网站优化公司开始上班了
  • 嘉兴网站推广企业站长工具seo推广
  • 东莞做网站多少钱seo外链代发
  • 黑龙江省住房和建设厅网站2021百度新算法优化
  • 网站栏目策划 有思想的新闻seo成都培训
  • 罗阳网站建设天津做优化好的公司
  • 网站设计实施方案新媒体运营是做什么
  • 珠海十大网站建设公司哪家好搜狗快速收录方法
  • 做网页的it网站重庆seo排名软件
  • 北京企业官网网站建设关键词有几种类型
  • 销售网站开发步骤石景山区百科seo
  • 网易企业邮箱手机端登录不上咋办seo零基础入门到精通200讲
  • dw做网站字体 别人电脑显示北京营销推广公司
  • 网站建设模板代理关键词热度分析工具
  • 建设网站要点seo算法优化
  • 赣州章贡区旅游景点温州seo团队
  • 六数字域名做网站好不好电商网站设计
  • 做网站的人是什么职位软文营销的经典案例
  • 个人可以建设哪些网站郑州抖音seo
  • 建站一般要多少钱如何做好网络营销推广
  • 模板手机网站建设公司seo优化排名易下拉效率
  • 滕州营销型网站建设百度seo排名优化费用
  • 华夏望子成龙网站开发背景百度推广是什么工作
  • 南京网站建设的公司优化大师官方