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

wordpress暴力破解seo视频教程汇总

wordpress暴力破解,seo视频教程汇总,做外贸好还是跨境电商好,如何网站建设平台GitHub - yzfzzz/MyWebServer: Linux高并发服务器项目,参考了TinyWebServer,将在此基础上进行性能改进与功能增加。为方便读者学习,附带详细注释和博客! TinyWebserver的复现与改进(1):服务器环…

GitHub - yzfzzz/MyWebServer: Linux高并发服务器项目,参考了TinyWebServer,将在此基础上进行性能改进与功能增加。为方便读者学习,附带详细注释和博客!

webserver

TinyWebserver的复现与改进(1):服务器环境的搭建与测试-CSDN博客

TinyWebserver的复现与改进(2):项目的整体框架-CSDN博客

TinyWebserver的复现与改进(3):线程同步机制类封装及线程池实现-CSDN博客

Reactor模式

今天我们将采用主从Reactor多线程模式,这是是大多数高性能服务器采用的模式

主从Reactor多线程模式要求主线程(I/O处理单元)只需负责:

  1. 监听文件描述符上是否有事件发生,
  2. 有的话就立即将该事件通知工作线程(逻辑单元),
  3. 将 socket 可读可写事件放入请求队列,交给工作线程处理。

除此之外,主线程不做任何其他实质性的工作。读写数据,接受新的连接,以及处理客户请求均在工作线程中完成。

Reactor模式的工作流程

使用同步 I/O(以 epoll_wait 为例)实现的 Reactor 模式的工作流程是:

  1. 主线程往 epoll 内核事件表中注册 socket 上的读就绪事件。 (即把listenfd、和已连接的客户端socketfd加入到epoll模型中)
  2. 主线程调用 epoll_wait 等待 socket 上有数据可读。
  3. 当 socket 上有数据可读时, epoll_wait 通知主线程。主线程则将 socket 可读事件放入请求队列。
  4. 正在堵塞的某个工作线程被解除堵塞,它从 socket 读取数据,并处理客户请求,然后往 epoll 内核事件表中注册该 socket 上的写就绪事件。
  5. 当主线程调用 epoll_wait 等待 socket 可写。
  6. 当 socket 可写时,epoll_wait 通知主线程。主线程将 socket 可写事件放入请求队列。
  7. 堵塞的某个工作线程被解除堵塞,它往 socket 上写入服务器处理客户请求的结果。

image-20240812174758935

代码实现

main函数流程图如图所示:

image-20240812181143205

初始化

创建线程池
// 定义一个线程池指针
threadpool<http_conn>* pool = NULL;
try {// 开辟一个线程池pool = new threadpool<http_conn>;
}catch(...)
{// 若异常则退出return 1;
}

使用new创建一个http_conn类型的线程池,返回的指针由pool接收。由于使用了 try……catch(...)语句,因此如果遇到异常则退出

创建客户端集合
// 开辟一块连续的http_conn数组,保存所有正在连接的客户端信息
http_conn* users = new http_conn[MAX_FD];

创建一个大小为 MAX_FD 的 http_conn 数组,当接收一个新 socket_fd 时,将会在 索引 i = socket的数组处(即 users[socket_fd]),初始化一个 http_conn 对象。这个对象保存着该客户端的所有信息。

创建监听
// 设置监听
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
int ret = 0;
struct sockaddr_in address;
address.sin_addr.s_addr = INADDR_ANY;	// 表示本机的所有IP都可以连接客户端
address.sin_family = AF_INET;  // 使用ipv4
address.sin_port = htons(port);// 设置端口复用
int reuse = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));// 绑定
ret = bind(listenfd, (struct sockaddr*)&address, sizeof(address));
if(ret == -1)
{
perror("bind");
exit(-1);
}// 开始监听
ret = listen(listenfd, 5);
if(ret == -1)
{
perror("listen");
exit(-1);
}
  1. socket 创建一个套接字,AF_INET表示使用 ipv4,SOCK_STREAM表示使用流式协议,和后面的0搭配表示使用的是TCP协议

  2. 但此时的socket,没有主机的端口号和ip信息,我们需要使用结构体address存储主机的相关信息:如IP(address.sin_addr.s_addr = INADDR_ANY)、ipv4(address.sin_family = AF_INET)、端口(address.sin_port = htons(port)),其中 htons() 表示 主机字节序 => 网络字节序 ,因为不同的机器在内存中的存放字节的顺序不同,我们需要统一标准

  3. 假设用户先运行./server.out,关闭后再快速运行./server.out,会报错:该端口被占用。这是因为结束./server,服务端处于FIN_WAIT状态,可以认为TCP通讯的TIME_WAIT时期需要等一小段时间。为了解决这个问题,常用setsockopt()表示开启端口复用功能。

  4. bind 将fd 和本地的IP和端口进行绑定,然后开始监听

epoll初始化
// 将listend添加到epoll模型中
epoll_event events[MAX_EVENT_NUMBER];
int epollfd = epoll_create(5);
addfd(epollfd, listenfd, false);
http_conn::m_epollfd = epollfd;

1.epoll_event用于检测文件描述符发生了什么事情(如读事件、写事件等)

2.addfd表示将listenfd加入epollfd中,这是一个自定义函数

epoll轮询

int number = epoll_wait(epollfd, events, MAX_EVENT_NUMBER,-1);

如果没有数据发送给服务器,将一直堵塞再此处

事件处理

有新客户端连接
 // 有新的客户端连接
if(sockfd == listenfd)
{struct sockaddr_in client_address;socklen_t client_addresslen = sizeof(client_address);int connfd = accept(listenfd, (struct sockaddr*)&client_address, &client_addresslen);if(connfd < 0)
{printf("errno is %d\n", errno);continue;
}if(http_conn::m_user_count >= MAX_FD)
{close(connfd);continue;
}users[connfd].init(connfd, client_address);
}
可读
// 有读事件发生(可读)
else if(events[i].events & EPOLLIN)
{// 有读事件发生if(users[sockfd].read()){// 读的到数据pool->append(users+sockfd);}else{// 读不到数据users[sockfd].close_conn();}
}
可写
// 有写事件发生(可写)
else if(events[i].events & EPOLLOUT)
{if(!users[sockfd].write()){users[sockfd].close_conn();}
}

结束

close(epollfd);
close(listenfd);
delete [] users;
delete pool;
return 0;

关闭所有的fd

完整代码

#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include "threadpool.hpp"
#include "locker.h"
#include "http_conn.h"
#include <signal.h>
#include <assert.h>  #define MAX_FD 65536  // 最大的文件描述符
#define MAX_EVENT_NUMBER 10000 // 监听的最大事件数/* 函数指针的声明: 类型说明符 (*函数名) (参数)void(handler)(int) 声明了一个名为 handler 的函数指针,它指向一个接受一个 int 参数并返回 void 的函数
*/
void addsig(int sig, void(handler)(int))
{// sigaction的输入参数struct sigaction sa;// 指定sa内存区域的前n个字节都设置为某个特定的值('\0'),用于对新分配的内存进行初始化memset(&sa, '\0', sizeof(sa));// 写入函数指针,指向的函数就是信号捕捉到之后的处理函数sa.sa_handler = handler;// 设置临时阻塞信号集sigfillset(&sa.sa_mask);assert(sigaction(sig, &sa, NULL) != -1);
}int main(int argc, char* argv[])
{if(argc <= 1){// 要求输入格式为 ./a.out 10000  其中10000是端口号 printf("usage: %s port_number\n", basename(argv[0]));return 1;}// 端口号 string -> intint port = atoi(argv[1]);// 如果向一个没有读端的管道写数据,不用终止进程addsig(SIGPIPE, SIG_IGN);   // SIG_IGN: 忽略信号,这里指的是忽略信号 ·  SIGPIPE// 定义一个线程池指针threadpool<http_conn>* pool = NULL;try {// 开辟一个线程池pool = new threadpool<http_conn>;}catch(...){// 若异常则退出return 1;}// 开辟一块连续的http_conn数组,保存所有正在连接的客户端信息http_conn* users = new http_conn[MAX_FD];// 设置监听int listenfd = socket(AF_INET, SOCK_STREAM, 0);int ret = 0;struct sockaddr_in address;address.sin_addr.s_addr = INADDR_ANY;address.sin_family = AF_INET;address.sin_port = htons(port);// 设置端口复用int reuse = 1;setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));// 绑定ret = bind(listenfd, (struct sockaddr*)&address, sizeof(address));if(ret == -1){perror("bind");exit(-1);}// 开始监听ret = listen(listenfd, 5);if(ret == -1){perror("listen");exit(-1);}// 将listend添加到epoll模型中epoll_event events[MAX_EVENT_NUMBER];int epollfd = epoll_create(5);addfd(epollfd, listenfd, false);http_conn::m_epollfd = epollfd;while(1){// epoll轮询,等待有数据发送int number = epoll_wait(epollfd, events, MAX_EVENT_NUMBER,-1);if((number < 0) && (errno != EINTR)){printf("epoll failture\n");break;}for(int i = 0; i < number; i++){int sockfd = events[i].data.fd;// 有新的客户端连接if(sockfd == listenfd){struct sockaddr_in client_address;socklen_t client_addresslen = sizeof(client_address);int connfd = accept(listenfd, (struct sockaddr*)&client_address, &client_addresslen);if(connfd < 0){printf("errno is %d\n", errno);continue;}if(http_conn::m_user_count >= MAX_FD){close(connfd);continue;}users[connfd].init(connfd, client_address);}// 若对方异常端开或错误else if(events[i].events & (EPOLLRDHUP | EPOLLHUP | EPOLLERR)){users[sockfd].close_conn();}// 有读事件发生(可读)else if(events[i].events & EPOLLIN){// 有读事件发生if(users[sockfd].read()){// 读的到数据pool->append(users+sockfd);}else{// 读不到数据users[sockfd].close_conn();}}// 有写事件发生(可写)else if(events[i].events & EPOLLOUT){if(!users[sockfd].write()){users[sockfd].close_conn();}}}}close(epollfd);close(listenfd);delete [] users;delete pool;return 0;
}
http://www.dinnco.com/news/10103.html

相关文章:

  • wordpress 缩略图类型知乎seo
  • 网站怎么建设上海百度移动关键词排名优化
  • 网站建设中的思想和算法近三年成功的营销案例
  • h5case 网站百度代理合作平台
  • 音乐网站怎么做社交的营销宣传方式有哪些
  • 章丘哪里做网站衡水seo培训
  • 做党政板报的网站北京发生大事了
  • 组建网站开发团队房地产营销策略有哪些
  • 数据库 网站开发所需流程免费优化推广网站的软件
  • 丰台网站建设联系方式aso关键词覆盖优化
  • 网上购物商城网站建设毕业设计百度搜索引擎营销
  • 网站建设linux快手seo软件下载
  • 网站备案密码 多少位百度快照客服
  • 企业网站哪个好百度客服中心
  • 一台vps可以做几个网站手机百度极速版app下载安装
  • 什么是wordpress主题武汉网络推广seo
  • 企业网站开发多少钱seo搜索引擎入门教程
  • 做一个购物网页优化网站的目的
  • php网站开发软件是什么潍坊seo教程
  • 小语种网站案例郑州网站关键词优化公司哪家好
  • 找网站建设企业某网站seo诊断分析
  • asp.net 网站建设免费网站流量
  • 全国政务网站哪家做的好网站开发流程
  • 做网站需要买什么东西网站域名备案信息查询
  • 可以举报一个做网络网站发大财吗最近新闻摘抄50字
  • 哈尔滨网站制作维护盘古百度推广靠谱吗
  • 网站制作文案杭州杭州线上推广
  • 济阳做网站哪家好搜索引擎搜索器
  • 网站建设好后如何连接服务器免费顶级域名注册
  • 淘宝优惠券网站怎么做班级优化大师官网登录