从零实现HTTP服务器
响应:
第一部分测试代码,读取请求
Makefile
bin=httpserver #生成的可执行程序
cc=g++ #编译器名称
LD_FLAGS=-std=c++11 -lpthread #-DDEBUG=1 #链接选项
src=main.cc$(bin):$(src)$(cc) -o $@ $^ $(LD_FLAGS).PHONY:clean
clean:rm -f $(bin)
1111111
main.cc
#include <iostream>
#include <string>
#include <memory>
#include "HttpServer.hpp"
static void Usage(std::string proc)
{std::cout << "Usage:\n\t" << proc << " port" << std::endl;;
}int main(int argc, char *argv[])
{if( argc != 2 ){Usage(argv[0]);exit(4);}int port = atoi(argv[1]);std::shared_ptr<HttpServer> http_server(new HttpServer(port));http_server->InitServer();http_server->Loop();return 0;
}
11111
Log.hpp
#pragma once#include <iostream>
#include <string>
#include <ctime>#define INFO 1
#define WARNING 2
#define ERROR 3
#define FATAL 4#define LOG(level, message) Log(#level, message, __FILE__, __LINE__)void Log(std::string level, std::string message, std::string file_name, int line)
{ // [日志级别][时间戳][日志信息][错误文件名称][行数]std::cout << "[" << level << "]" << "[" << time(nullptr) << "]" << "[" << message << "]" << "[" << file_name << "]" << "[" << line << "]" << std::endl;
}
111
TcpServer.hpp
#pragma once#include <iostream>
#include <cstdlib>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include "Log.hpp"#define BACKLOG 7class TcpServer
{private:int _port;int _listen_sock;static TcpServer* _svr; // 指向单例对象的static指针,懒汉模式private: // 单例模式TcpServer(int port): _port(port), _listen_sock(-1){}TcpServer(){}TcpServer(const TcpServer& s) = delete;TcpServer* operator=(const TcpServer& s) = delete;public:static TcpServer *GetInstance(int port){static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;if(nullptr == _svr){pthread_mutex_lock(&lock);if(nullptr == _svr){_svr = new TcpServer(port);_svr->InitServer();}pthread_mutex_unlock(&lock);}return _svr;}void InitServer(){Socket();Bind();Listen();LOG(INFO, "tcp_server init ... success");}void Socket(){_listen_sock = socket(AF_INET, SOCK_STREAM, 0);if(_listen_sock < 0){LOG(FATAL, "socket error");exit(1);}int opt = 1; // 端口复用:宕机了也能立马绑定端口号setsockopt(_listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));LOG(INFO, "create socket ... success");}void Bind(){struct sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(_port);local.sin_addr.s_addr = INADDR_ANY; //云服务器不能直接绑定公网IPif(bind(_listen_sock, (struct sockaddr*)&local, sizeof(local)) < 0){LOG(FATAL, "bind error");exit(2);}LOG(INFO, "bind socket ... success");}void Listen(){if(listen(_listen_sock, BACKLOG) < 0){LOG(FATAL, "listen socket error");exit(3);}LOG(INFO, "listen socket ... success");}int Sock(){return _listen_sock;}~TcpServer(){if(_listen_sock >= 0){close(_listen_sock);}}
};TcpServer* TcpServer::_svr = nullptr;
11111111
HttpServer.hpp
#pragma once#include <iostream>
#include <pthread.h>
#include <signal.h>
#include "Log.hpp"
#include "TcpServer.hpp"
#include "Protocol.hpp"#define PORT 7777class HttpServer
{private:int _port;bool _stop;public:HttpServer(int port = PORT): _port(port), _stop(false){}void InitServer(){// 信号SIGPIPE进行忽略,否则在写入时候,可能直接崩溃serversignal(SIGPIPE, SIG_IGN); }void Loop(){TcpServer *tsvr = TcpServer::GetInstance(_port);LOG(INFO, "Loop begin");while(!_stop){struct sockaddr_in peer;socklen_t len = sizeof(peer);int sock = accept(tsvr->Sock(), (struct sockaddr*)&peer, &len);if(sock < 0) // 获取套接字失败{continue;}LOG(INFO, "Get a new link");int *_sock = new int(sock); // 暂时方案pthread_t pid;pthread_create(&pid, nullptr, Entrance::HandlerRequest, _sock);pthread_detach(pid);}}~HttpServer(){}
};
1111
Protocol.hpp
#pragma once#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "Log.hpp"
#include "Util.hpp"#define DEBUG
class Entrance // 线程入口
{
public:Entrance(){}~Entrance(){}static void* HandlerRequest(void * _sock){int sock = *(int*)_sock; // 临时测试方案LOG(INFO, "Hander Request Begin");
#ifdef DEBUG//For Testchar buffer[4096];recv(sock, buffer, sizeof(buffer), 0);std::cout << "-------------begin----------------" << std::endl;std::cout << buffer << std::endl;std::cout << "-------------end----------------" << std::endl;
#else EndPoint* ep = new EndPoint(sock);ep->RecvHttpRequest();ep->BuildHttpResponse();ep->SendHttpResponse();delete ep;
#endifLOG(INFO, "Hander Request End");}
};
测试结果
11111
第二部分测试代码,解析请求,返回静态网页
过程截图:
读取请求行和报头
解析uri:
返回了静态网页:
telnet测试:
加上了响应类型和长度:
第二份代码链接:
Linux_Code: 存放linux学习代码 - Gitee.com
相关文章:
从零实现HTTP服务器
响应: 第一部分测试代码,读取请求 Makefile binhttpserver #生成的可执行程序 ccg #编译器名称 LD_FLAGS-stdc11 -lpthread #-DDEBUG1 #链接选项 srcmain.cc$(bin):$(src)$(cc) -o $ $^ $(LD_FLAGS).PHONY:clean clean:rm -f $(bin) 1111111 main.cc…...
智能检索知识库
一、智能检索知识库作用 1. 提升信息检索效率,降低人力成本 快速获取精准答案:员工无需手动翻阅大量文档(如产品手册、合同、技术文档),直接通过自然语言提问获取答案。 减少重复性工作:HR、客服、技…...
北斗导航 | 接收机自主完好性监测(RAIM)算法学习思路总结及其算法研究:理论、实现与验证
===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 接收机自主完好性监测学习思路 壹、学习思路贰、理论、实现与验证1. 引…...
无法读取库伦值文件节点解决方案
读取库伦值的目的是为了换算成电流,量化场景功耗用途 1.报错日志 /power_log/debuglogger$ adb shell dmesg | grep -Ei "avc..system_server"[ 79.942272] logd.auditd: type1400 audit(1744279324.832:7149): avc: denied { read } for comm"…...
OCR API识别对比
OCR 识别DEMO OCR识别 demo 文档由来 最开始想使用百度开源的 paddlepaddle大模型 研究了几天,发现表格识别会跨行,手写识别的也不很准确。最终还是得使用现成提供的api。。 文档说明 三个体验下来 腾讯的识别度比较高,不论是手写还是识别表…...
高速电路设计概述
1.1 低速设计和高速设计的例子 本节通过一个简单的例子,探讨高速电路设计相对于低速电路设计需要考虑哪些不同的问题。希望读者通过本例,对高速电路设计建立一个表象的认识。至于高速电路设计中各方面的设计要点,将在后续章节展开详细的讨论…...
Keil C51中32位变量赋值异常问题分析与解决
Keil C51中32位变量赋值异常问题分析与解决 问题描述 在使用Keil5对51单片机进行编程时,遇到一个32位变量赋值不正确的问题。具体代码如下: typedef unsigned long uint32;g_Flow_Time (uint32)Storage[2] << 24 | Storage[3] << 16 | S…...
python工程中的包管理(requirements.txt)
pip install -r requirements.txtpython工程通过requirements.txt来管理依赖库版本,上述命令,可以一把安装依赖库,类似java中maven的pom.xml文件。 参考 [](...
用Python修改字体字形与提取矢量数据:fontTools实战指南
字体设计与分析是NLP和视觉领域的交叉应用,而**fontTools** 是一款强大的Python库,可以让我们直接操作字体文件的底层结构。本文将通过两个实用函数,展示如何修改特定字形和提取所有字形的矢量数据,帮助开发者快速上手字体编辑与分…...
数据库守护神-WAL机制
什么是WAL机制? WAL(Write-Ahead Logging,预写日志)是一种保证数据库操作原子性和持久性的核心机制。其核心原则可概括为: 任何数据修改操作,必须在对应的日志记录持久化到磁盘之后,才能将实际…...
[MySQL]数据库与表创建
欢迎来到啾啾的博客🐱。 这是一个致力于构建完善 Java 程序员知识体系的博客📚。 它记录学习点滴,分享工作思考和实用技巧,偶尔也分享一些杂谈💬。 欢迎评论交流,感谢您的阅读😄。 本篇简单记录…...
工作记录 2015-05-27
工作记录 2015-05-27 序号 工作 相关人员 1 修改了指定短语的大小写的处理。 取消了一些逗号的处理。 郝 另: iCDA更新到了190的D:\Temp\CHTeam\iCDA_20150527下了 修改的文件: bin目录下是程序。 0223目录下是0223的一些设置和关键字。 更新…...
嵌入式汇编语言从小白到入门:从零开始的底层编程之旅
嵌入式汇编语言从小白到入门:从零开始的底层编程之旅 汇编语言作为最接近机器语言的编程方式,在嵌入式开发中扮演着不可替代的角色。本文将带你从零开始,逐步掌握嵌入式汇编语言的核心概念和实践技巧,最终能够独立编写简单的汇编程序并与C语言混合编程。 一、汇编语言与嵌…...
GPIO_ReadInputData和GPIO_ReadInputDataBit区别
目录 1、GPIO_ReadInputData: 2、GPIO_ReadInputDataBit: 总结 GPIO_ReadInputData 和 GPIO_ReadInputDataBit 是两个函数,通常用于读取微控制器GPIO(通用输入输出)引脚的输入状态,特别是在STM32系列微控制器中。它们之间的主要…...
不使用docker在本地安装与配置RAGFlow
RAGFlow 本地安装与配置(非docker方式) 一. 运行环境 windows10 CPU i7-12700F 2.10GHz内存 32GGPU RTX 4060 Ti 8G wsl 2 Ubuntu-22.04 1. 防火墙配置 wsl默认访问windows的本机服务需要配置防火墙,否则访问会失败。 windows10的防火墙配置: 打…...
sysfs 设备模型
介绍 Sysfs 设备文件系统与proc是同一类的文件系统,基于ramfs实现的内存文件系统。 1.1 为什么会有 sysfs?procfs 的局限性: 早期,Linux 使用 procfs 来提供内核与用户空间的交互接口。但 procfs 的设计不够层次化,设…...
彩讯携Rich AICloud与一体机智算解决方案亮相中国移动云智算大会
2025年4月10日,2025中国移动云智算大会在苏州盛大开幕,本次大会以“由云向智 共绘算网新生态”为主题,与会嘉宾围绕算力展开重点探讨。 大会现场特设区域展出各参会单位的最新算力成果,作为中国移动重要合作伙伴,彩讯…...
js触发隐式类型转换的场景
JavaScript 的隐式类型转换(Implicit Type Coercion)会在某些操作或上下文中自动触发,将值从一种类型转换为另一种类型。以下是常见的触发场景: 1. 使用 (宽松相等)比较时 会尝试将两边的值转换为相同类型后…...
《AI大模型应知应会100篇》第9篇:大模型的推理能力:原理与实现
第9篇:大模型的推理能力:原理与实现 摘要 近年来,随着大语言模型(LLM)的快速发展,其推理能力逐渐成为研究和应用中的热点话题。这些模型不仅能够生成流畅的文本,还能在一定程度上进行逻辑推理、…...
PODS_ROOT、BUILT_PRODUCTS_DIR和SRCROOT有什么区别
在 iOS/macOS 开发中,${PODS_ROOT}、${BUILT_PRODUCTS_DIR} 和 ${SRCROOT} 是三个核心的 Xcode 环境变量,它们的区别主要体现在 目录层级、内容归属 和 生命周期 上。以下是结构化对比和具体示例: 1. 定义与作用域对比 变量全称指向路径管理…...
Elasticsearch 系列专题 - 第六篇:高级功能与生态系统
Elasticsearch 不仅是一个强大的搜索引擎,还提供了高级功能和丰富的生态系统支持。本篇将深入探讨这些特性,并介绍如何与其他工具协同工作。 1. 高级特性 1.1 跨集群搜索(Cross-Cluster Search) 跨集群搜索允许查询多个独立集群的数据,适用于分布式系统。 配置远程集群:…...
python的web框架flask(hello,world版)
问题 最近需要基于一个开源项目进行二次开发,但是,现在的我主修java,从来没有接触过python的web开发。所以,我现在需要学习一下flask的hello,world。 python版本选择 通过这个Python版本状态页面Status of Python v…...
Vue学习笔记 - 逻辑复用 - 组合式函数
昨天参加了次视频面试,慢慢可以查漏补缺,继续学习Vue相关的知识,考虑找个实际的开源项目。 逻辑复用 组合式函数 在 Vue 应用的概念中,“组合式函数”(Composables) 是一个利用 Vue 的组合式 API 来封装和复用有状态逻辑的函数。 无状态的…...
Caffeine的两种实现方式
咱们来具体对比一下你之前给的这段配置代码👇: java Configuration EnableCaching public class CacheConfig { Bean public CacheManager cacheManager() { CaffeineCacheManager manager new CaffeineCacheManager("myCache"); manager.…...
单细胞Seurat标准分析流程R语言封装
单细胞Seurat标准分析流程R语言封装 数据预处理与质控(线粒体基因比例计算、QC图表生成)标准化与高变基因筛选PCA/UMAP降维与聚类分析 差异表达分析模块自动化输出PNG可视化图表(质控小提琴图、UMAP聚类图)结果将保存在results/和figures/目录下(RDS对象、差异基因CSV表格…...
MOS管的发热原因和解决办法
发热来源 如上图,MOS管的工作状态有4种情况,分别是开通过程,导通过程,关断过程和截止过程。 导致发热的损耗主要有两种:开关损耗、导通损耗。 导通损耗 导通损耗比较好计算,根据驱动电压VGS值可以得到MOS…...
航顺HK32M070电钻解决方案:驱动未来,掌控无限可能
一、市场规模与增长:电动工具行业持续扩容,电钻需求强劲 全球电动工具市场规模近年来保持稳定增长,2023年市场规模已达288.5亿美元,预计2024年将突破304.9亿美元,年复合增长率达6.9%。中国市场表现尤为亮眼࿰…...
关于nacos注册的服务的ip异常导致网关路由失败的问题
文章目录 关于nacos注册的服务的ip异常导致网关路由失败的问题相关处理方案为方案一:手动指定服务注册的 IP 地址方法二:设置优先使用的网络段方法三:指定网络接口方法四:忽略特定的网卡 备注 关于nacos注册的服务的ip异常导致网关路由失败的…...
UI测试流程与关键注意点解析
在当今以用户体验为核心的数字时代,用户界面(UI)作为软件与用户交互的直接窗口,其质量直接影响着产品的成败。UI测试作为软件测试的重要组成部分,确保应用程序不仅功能完善,而且在视觉呈现和交互体验上也能满足用户期望。 作为软…...
从零开始构建智能聊天机器人:Rasa与ChatGPT API实战教程
引言:AI对话系统的时代机遇 在数字化转型浪潮中,聊天机器人已成为连接用户与服务的关键纽带。无论是客服系统中的724小时即时响应,还是智能家居中的语音交互,聊天机器人正在重塑人机交互方式。本文将通过详细教程,手把…...
SSM aop切面编程的学习
面向切面的AOP编程的引入: 1. 代码缺陷 - 非核心代码对核心业务功能有干扰,导致程序员在开发核心业务功能时分散了精力 - 附加功能代码重复,分散在各个业务功能方法中!冗余,且不方便统一维护! 2. 解决思路 …...
Zen 5白色装机优选,华硕X870 AYW GAMING WIFI W主板来了!
华硕X870/X870E系列主板再次迎来新成员——华硕X870 AYW GAMING WIFI W主板正式发售!专为追求高性价比游戏玩家而量身打造,延续AYW系列经典SPACE太空元素,配合大面积银白色散热装甲,打造出了极具金属质感和科技感的外观࿰…...
第Y1周:调用YOLOv5官方权重进行检测
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 文章目录 1、前言2、下载源码3、运行代码 1、前言 YOLOv5分为YOLOv5s、YOLOv5m、YOLOv5l、YOLOv5x四个版本,这里以YOLOv5s为例。 2、下载源码 安…...
科技项目验收测试怎么做?验收测试报告如何获取?
科技项目从研发到上市需要一个很长的周期,并且在上市之前还有一个至关重要的交付过程,那就是项目验收,验收需要通过验收测试来呈现。科技项目验收测试是确保项目成功交付的关键步骤,那么是如何进行的呢?企事业单位想要获取科技项…...
C++笔记
C知识笔记 一、C概述 C是一种通用编程语言,它在C语言的基础上扩展而来,支持面向对象编程、泛型编程和过程化编程等多种编程范式。C具有高效、灵活、接近硬件等特点,广泛应用于系统软件、应用软件、嵌入式系统、游戏开发等领域。其强大的性能…...
国产Linux统信安装mysql8教程步骤
系统环境 uname -a Linux FlencherHU-PC 6.12.9-amd64-desktop-rolling #23.01.01.18 SMP PREEMPT_DYNAMIC Fri Jan 10 18:29:31 CST 2025 x86_64 GNU/Linux下载离线安装包 浏览器下载https://downloads.mysql.com/archives/get/p/23/file/mysql-test-8.0.33-linux-glibc2.28…...
如何应对“最后时刻任务堆积”(鼓包现象)
应对“最后时刻任务堆积”(鼓包现象)的方法包括:合理规划项目时间表、强化进度跟踪管理、明确任务优先级、有效的资源配置、提升团队沟通效率。其中,强化进度跟踪管理尤为关键。根据项目管理协会(PMI)的调查…...
C语言,原码、补码、反码
计算机是以补码来存储的 原码:正数最高位为:0;负数最高位为:1 (最高位是符号位) 正数:三码合一 如:2: 原码:0000 0000 0000 0000 0000 0000 0000 0010&#…...
Unifying Short and Long-Term Tracking with Graph Hierarchies—CVPR2023
Unifying Short and Long-Term Tracking with Graph Hierarchies 博客目录 Unifying Short and Long-Term Tracking with Graph Hierarchies摘要概况引言和相关介绍提出的观点 SUSHI核心构建跟踪图的层次结构构建分层剪辑分区 做第二个创新模块的需要将研究的重点从处理遮挡的问…...
深入解析 C# 中的模板方法设计模式
模板方法设计模式(Template Method Pattern)是行为型设计模式中的一种,它定义了一个操作中的算法框架,并允许子类在不改变算法整体结构的情况下,重新定义该算法的某些步骤。该模式通常用于类中包含一系列固定步骤的算法…...
0411 | 软考高项笔记:项目立项
在软考的项目管理知识体系中,技术可行性和经济可行性是项目立项阶段非常重要的两个分析维度。以下是对这两个考点的详细解释和记忆方法: 技术可行性分析 定义: 技术可行性分析是评估项目在现有技术条件和资源下是否能够成功实施。它主要回答…...
ubnetu 服务器版本常用端口和开放的端口对应的应用
1. 使用 netstat 查看端口与进程 netstat 是查看网络连接和监听端口的常用工具。通过以下命令可以列出所有开放的TCP/UDP端口及其关联的进程: sudo netstat -tulnp参数解析: -t:显示TCP端口。 -u:显示UDP端口。 -l࿱…...
【服务器端表单字符验证】
文章目录 一、实验目的二、核心代码实现三、调试关键问题四、总结 一、实验目的 掌握JSP表单验证在服务器端的实现技术,实现对用户输入字符的非空及长度为5的验证,返回对应提示信息并优化用户交互。 二、核心代码实现 前端表单 <form action"…...
pip 与 conda 的全面比较:Python 包管理的深度解析
在 Python 的生态系统中,包管理工具是开发者日常工作的重要组成部分。其中,pip 和 conda 是最常用的两种包管理工具。虽然它们在功能上有一些重叠,但在设计理念、功能范围、依赖管理、环境隔离等方面存在显著差异。本文将从多个维度深入…...
GTID不一致修复
背景描述 GTID模式下,mysql主从切换后,主从同步报错 Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION 1, but the master has purged bi…...
conda-pack打包环境到超算上。解决无法打包可编辑包
conda-pack 打包 使用 conda-pack 打包 Conda 环境可以将整个环境打包成一个独立的可移植压缩包,方便在其他机器上解压使用。以下是具体步骤: 1.安装 conda-pack 首先需要安装 conda-pack。你可以通过 conda 或 pip 安装: conda install …...
O(n)复杂度实现寻找数组第k小的数(快速选择算法)
非堆排序实现,利用快速排序思想实现的快速选择 package algorithm;public class Test {public int quickSelect(int nums[], int left, int right, int k){if (left right) return nums[left];int i left - 1, j right 1, x nums[left];while (i < j){do i…...
利用 RNN 预测股票价格:从数据处理到可视化实战
在金融领域,预测股票价格走势一直是众多投资者和研究者关注的焦点。今天,我们将利用深度学习中的循环神经网络(RNN)来构建一个简单的股票价格预测模型,并详细介绍从数据加载、预处理、模型搭建、训练到最终结果可视化的…...
前端从全链路角度分析性能
在面试中回答“从全链路角度分析性能优化”时,需覆盖用户请求到页面渲染的完整链路。以下是结构化回答框架,结合业界实践和最新优化策略: 一、网络传输优化 1. CDN与协议升级 ◦ 使用CDN缩短资源物理距离,结合HTTP/2/3的多路复用和头部压缩特性,提升资源加载效率(如We…...
2025年第十八届“认证杯”数学中国数学建模网络挑战赛【BC题】完整版+代码+结果
# 问题一:随机森林回归from sklearn.ensemble import RandomForestRegressormodel_rf RandomForestRegressor()model_rf.fit(X_train, y_train)# 问题二:LSTM时间序列预测from tensorflow.keras.models import Sequentialmodel_lstm Sequential()model…...