使用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.pswp.cn/news/900066.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/900066.shtml
英文地址,請注明出處:http://en.pswp.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 如何使用指針數組模擬二維數組 上…