使用C++实现HTTP服务

天天开心!!!
阅读本篇文章之前,请先阅读HTTP基础知识

传送门----> HTTP基础知识

文章目录

  • 一、C++Web服务器(核心代码WebServer.cpp)
  • 二、静态文件结构
  • 三、编译和运行
  • 四、访问测试


一、C++Web服务器(核心代码WebServer.cpp)

要实现一个简单的C++Web服务器,支持GET和POST请求,同时能够提供静态文件(如JavaScript、CSS和图片文件)。

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <unordered_map>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/stat.h>
using namespace std;#define PORT 8080   // 端口号#define BUFFER_SIZE 4096   // 缓冲区大小//根据文件拓展名返回适当的Content-Type
std::string getContentType(const std::string &path){if(path.ends_with(".html")) return "text/html";if(path.ends_with(".css")) return "text/css";if(path.ends_with(".js")) return "application/javascript";if(path.ends_with(".png")) return "image/png";if(path.ends_with(".jpg")) return "image/jpeg";if(path.ends_with(".jpeg")) return "image/jpeg";if(path.ends_with(".gif")) return "image/gif";return "text/plain";}//读取静态文件
std::string readFile(const std::string &path){//创建一个输入文件流对象,以二进制模式打开指定路径的文件std::ifstream file(path,std::ios::binary);//检查文件是否成功打开if(!file.is_open()){perror("file open failed");//如果打开失败返回空字符串return "";}//创建一个输出字符串流对象,用于将文件内容读取到字符串std::ostringstream ss;//使用输出字符串流对象的rdbuf()将文件内容读取到字符串中//这实际上是将文件流中的所有字节复制到字符串流的缓冲区中ss<<file.rdbuf();//将字符串流的内容转换为std::string并返回return ss.str();}//判断文件是否存在
bool fileExists(const std::string &path){struct stat buffer;return stat(path.c_str(), &buffer)==0;
}int main() {// 创建套接字int server_fd, new_socket;// 地址结构体struct sockaddr_in address;int opt=1;  // 设置套接字选项int addlen = sizeof(address);// 地址结构体长度char buffer[BUFFER_SIZE] = {0};   // 缓冲区if ((server_fd = socket(AF_INET, SOCK_STREAM, 0))==0){perror("socket failed");exit(EXIT_FAILURE);}//设置端口复用//如果你不是用SO_REUSEADDR,服务器程序关闭后,可能会出现“Address already in use” 错误//尤其是当你尝试在同一个端口上重新启动服务器时,这是因为TCP连接可能会保持TIME_WAIT的状态一段时间//而SO_REUSEADDR允许套接字在这种状态下重新绑定到另一个端口if(setsoocketopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))){perror("setsoocketopt failed");exit(EXIT_FAILURE);}//配置服务器地址addrss.sin_family = AF_INET;addrss.sin_addr.s_addr = INADDR_ANY;addrss.sin_port = htons(PORT);//绑定套接字if(bind(server_fd, (struct sockaddr *)&address, addlen)<0){perror("bind failed");exit(EXIT_FAILURE);}//监听请求if(listen(server_fd, 3)<0){perror("listen failed");exit(EXIT_FAILURE);}cout<<"WebServer is running on port"<<PORT<<"....\n";while(true){//接受客户端连接if((new_socket=accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addlen))<0){perror("accept failed");exit(EXIT_FAILURE);}//读取客户端请求read(new_socket, buffer, BUFFER_SIZE);cout<<"Request received :\n"<<buffer<<endl;//解析Http请求//这段代码是解析Http请求中提取 请求方法、路径和Http版本。如下://第一次提取method,得到:GET//第二次提取path,得到:/index.html//第三次提取version,得到:HTTP/1.1std::istringstream request(buffer);std::string method , path , version;request>>method>>path>>version;//默认首页if(path=="/"){path="/index.html";}//构建文件路径std::string filePath ="."+path;//处理GET请求if(method=="GET"){if(fileExists(filePath)){//文件存在std::string content = readFile(filePath);//读取文件内容std::string contentType = getContentType(filePath);//获取文件类型std::ostringstream response;  // 构建响应response<<"HTTP/1.1 200 OK\r\n"<<"Content-Type:"<<contentType<<"\r\n"<<"Content-Length:"<<content.length()<<"\r\n"<<"\r\n"<<content;//响应头和响应体response<<content;//发送响应send(new_socket, response.str().c_str(), response.str().length(), 0);}else{//404 NOT FOUNDstd::string notFound="HTTP/1.1 404 Not Found\r\n\r\n404 Not Found";send(new_socket, notFound.c_str(), notFound.length(), 0);}}else if(method=="POST"){//处理POST请求//简单的响应客户端的POST请求(可以根据需要解析POST请求)std::string response="HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nPOST request";send(new_socket, response.c_str(), response.length(), 0);}else{//405 METHOD NOT ALLOWEDstd::string notAllowed="HTTP/1.1 405 Method Not Allowed\r\n\r\n405 Method Not Allowed";send(new_socket, notAllowed.c_str(), notAllowed.length(), 0);}//关闭连接close(new_socket);}//释放资源,关闭服务器套接字close(server_fd);return 0;
}

二、静态文件结构

  • 确保你的HTML、CSS、JS和图片文件都存放在与可执行程序相同的目录下或适当的子目录中,例如:
./index.html
./style.css
./script.js
./images/example.jjpg

在这里插入图片描述

假设HTL文件是这样的:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>这是一个简单的WebServer</title><style>body{font-family: Arial,sans-serif;background-color: #f4f4f9;color: #333;margin: 0;padding: 0;}header{background-color: #4CAF50;color: white;padding: 10px 0;}h1{margin: 0;}p{font-size: 1.2em;margin: 20px auto;width: 80%;}footer{position: fixed;bottom: 0;width: 100%;background-color: #4CAF50;color: white;padding: 10px 0;}</style>
</head>
<body>
<header><h1>这是一个简单的WebServer</h1>
</header>
<main><p>这是一个简单的WebServer,你可以在这里放置一些内容。</p><br/><img src="23.png" alt="C++测试">
</main>
<footer><p>&copy;2025 My WebServer By HuJiaHang</p>
</footer></body>
</html>

三、编译和运行

  • 编译
g++ -std=c++20 WebServer.cpp -o WebServer
//使用C++20标准,是因为std::string::ends_with()是C++20引入的功能
  • 运行:执行编译好的WebServer程序
./WebServer

四、访问测试

  • 使用浏览器访问http://localhost:8080,可以获取静态HTML页面、CSS样式、JavaScript脚本和图片
  • 注意:如果使用的是云服务器,就必须要在安全组中放开端口
  • 以下是我的测试
    在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/900066.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Reactive编程入门:Project Reactor 深度指南

文章目录 4.2.1 创建 Flux 和 MonoFlux 基础创建方式高级创建模式Mono 创建方式 4.2.2 订阅与数据处理基础订阅模式数据处理操作符 4.2.3 核心操作符深度解析flatMap 操作符zip 操作符buffer 操作符 高级组合模式复杂流处理示例背压处理策略 测试响应式流性能优化技巧 React 编…

【万字总结】前端全方位性能优化指南(完结篇)——自适应优化系统、遗传算法调参、Service Worker智能降级方案

前言 自适应进化宣言 当监控网络精准定位病灶&#xff0c;真正的挑战浮出水面&#xff1a;系统能否像生物般自主进化&#xff1f; 五维感知——通过设备传感器实时捕获环境指纹&#xff08;如地铁隧道弱光环境自动切换省电渲染&#xff09; 基因调参——150个性能参数在遗传算…

PQ以及有关索引的笔记Faiss: The Missing Manual

参考Faiss 索引结构总结&#xff1a; 为了加深记忆&#xff0c;介绍一下Inverted File Index&#xff08;IVF&#xff09;的名字由来&#xff1a; IVF索引的名字源自“倒排文件”&#xff08;Inverted File&#xff09;的概念。在传统的信息检索中&#xff0c;倒排文件是一种索…

win10彻底让图标不显示在工具栏

关闭需要不显示的软件 打开 例此时我关闭了IDEA的显示 如果说只是隐藏&#xff0c;鼠标拖动一个道理 例QQ 如果说全部显示不隐藏

关税核爆72小时!跨境矩阵防御战紧急打响

一、T86崩塌&#xff1a;全球贸易链的至暗时刻 &#xff08;配图&#xff1a;美国海关系统深夜弹出红色警报&#xff09; 5月2日凌晨2:17&#xff0c;杭州某光伏企业的供应链系统突然发出刺耳警报——其价值1800万美元的逆变器模块被划入34%关税清单。这场代号"黑天鹅突…

蓝桥杯Java B组省赛真题题型近6年统计分类

困难题 题号题型分值代码量难度通过率内容2024-F解答1581困难0.12最短路问题 Dijkstra 期望2024-G解答20116困难0.19模拟 暴力 搜索 DFS 剪纸 枚举2023-H解答2070困难0动态规划2022-H解答20109困难0.032022-J解答25141困难0搜索2021-H解答2041困难0.18二分 思维 规律2021-I解答…

【网络流 图论建模 最大权闭合子图】 [六省联考 2017] 寿司餐厅

题目描述&#xff1a; P3749 [六省联考 2017] 寿司餐厅 题目描述 Kiana 最近喜欢到一家非常美味的寿司餐厅用餐。 每天晚上&#xff0c;这家餐厅都会按顺序提供 n n n 种寿司&#xff0c;第 i i i 种寿司有一个代号 a i a_i ai​ 和美味度 d i , i d_{i, i} di,i​&…

前端面试题(三):axios有哪些常用的方法

Axios 是一个基于 Promise 的 HTTP 客户端&#xff0c;用于浏览器和 Node.js 中发送 HTTP 请求。它提供了一些常用的方法来处理不同类型的请求。以下是 Axios 中常用的一些方法&#xff1a; 1. axios.get() 用于发送 GET 请求&#xff0c;从服务器获取数据。 axios.get(/api/d…

python match case语法

学习路线&#xff1a;B站 普通的if判断 def if_traffic_light(color):if color red:return Stopelif color yellow:return Slow downelif color green:return Goelse:return Invalid colorprint(if_traffic_light(red)) # Output: Stop print(if_traffic_light(yellow)) …

LLaMA-Factory大模型微调全流程指南

该文档为LLaMA-Factory大模型微调提供了完整的技术指导&#xff0c;涵盖了从环境搭建到模型训练、推理和合并模型的全流程&#xff0c;适用于需要进行大模型预训练和微调的技术人员。 一、docker 容器服务 请参考如下资料制作 docker 容器服务&#xff0c;其中&#xff0c;挂…

【HCIA】静态综合实验练习笔记

实验拓扑图如下&#xff1a; 实验配置思路如下&#xff1a; 1、网段划分、配置IP地址 2、配置DHCP&#xff0c;使客户端获得ip地址 3、配置静态明细路由&#xff0c;内网全网通 4、配置空接口防环 5、配置优先级&#xff0c;实现选路最佳 6、配置缺省路由&#xff0c;实现公网通…

大数据(4.5)Hive聚合函数深度解析:从基础统计到多维聚合的12个生产级技巧

目录 背景一、Hive聚合函数分类与语法1. 基础聚合函数2. 高级聚合函数 二、6大核心场景与案例场景1&#xff1a;基础统计&#xff08;SUM/COUNT&#xff09;场景2&#xff1a;多维聚合&#xff08;GROUPING SETS&#xff09;场景3&#xff1a;层次化聚合&#xff08;ROLLUP&…

RTOS基础 -- NXP M4小核的RPMsg-lite与端点机制回顾

一、RPMsg-lite与端点机制回顾 在RPMsg协议框架中&#xff1a; Endpoint&#xff08;端点&#xff09; 是一个逻辑通信端口&#xff0c;由本地地址&#xff08;local addr&#xff09;、远程地址&#xff08;remote addr&#xff09;和回调函数组成。每个消息都会发送到特定的…

NineData云原生智能数据管理平台新功能发布|2025年3月版

本月发布 15 项更新&#xff0c;其中重点发布 3 项、功能优化 11 项、性能优化 1 项。 重点发布 基础服务 - MFA 多因子认证 新增 MFA 多因子认证&#xff0c;提升账号安全性。系统管理员开启后&#xff0c;所有组织成员需绑定认证器&#xff0c;登录时需输入动态验证码。 数…

DAY 35 leetcode 202--哈希表.快乐数

题号202 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。如果这个过程 结果为 1&a…

Maven+Spring实现后端开发

一、前置知识的介绍 1.Spring 轻量级的 DI / IoC 和 AOP 容器的开源框架 容器的开源框架网址&#xff1a;https://spring.io/projects/spring-framework 作用&#xff1a;可简化管理创建和组装对象之间的依赖关系 将controller----->service------->dao层的依赖配置…

解锁界面设计密码,打造极致用户体验

界面设计是对软件、网站、移动应用等产品的用户界面进行设计的过程&#xff0c;旨在为用户提供美观、易用、高效的交互体验。以下是关于界面设计的一些主要方面&#xff1a; 一、设计原则 用户中心原则&#xff1a;以用户为中心&#xff0c;了解用户的需求、期望、行为和习惯…

Joint Receiver Design for Integrated Sensing and Communications

摘要——在本文中&#xff0c;我们研究了集成感知与通信(ISAC)系统的联合接收机设计&#xff0c;其中通信信号和目标回波信号同时被接收和处理&#xff0c;以在两种功能之间实现平衡性能。特别地&#xff0c;我们提出了两种设计方案来解决联合感知和通信问题中的接收信号处理。…

DeepSeek接入飞书多维表格,效率起飞!

今天教大家把DeepSeek接入飞书表格使用。 准备工作&#xff1a;安装并登录飞书&#xff1b;可以准备一些要处理的数据&#xff0c;确保数据格式正确&#xff0c;如 Excel、CSV 等&#xff0c;也可直接存储到飞书多维表格。 创建飞书多维表格&#xff1a;打开飞书&#xff0c;点…

【C语言入门】由浅入深学习指针 【第二期】

目录 1. 指针变量为什么要有类型&#xff1f; 2. 野指针 2.1 未初始化导致的野指针 2.2 指针越界导致的野指针 2.3 如何规避野指针 3. 指针运算 3.1 指针加减整数 3.2 指针减指针 3.3 指针的关系运算 4. 二级指针 5. 指针数组 5.1 如何使用指针数组模拟二维数组 上…