公司网站免费建立,吉林省建设工程安管人员管理系统,上海最好的网吧,做网站需要干什么天天开心#xff01;#xff01;#xff01; 阅读本篇文章之前#xff0c;请先阅读HTTP基础知识 传送门---- HTTP基础知识 文章目录 一、CWeb服务器#xff08;核心代码WebServer.cpp#xff09;二、静态文件结构三、编译和运行四、访问测试 一、CWeb服务器#xff… 天天开心 阅读本篇文章之前请先阅读HTTP基础知识 传送门---- HTTP基础知识 文章目录 一、CWeb服务器核心代码WebServer.cpp二、静态文件结构三、编译和运行四、访问测试 一、CWeb服务器核心代码WebServer.cpp
要实现一个简单的CWeb服务器支持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()将文件内容读取到字符串中//这实际上是将文件流中的所有字节复制到字符串流的缓冲区中ssfile.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 opt1; // 设置套接字选项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);}coutWebServer is running on portPORT....\n;while(true){//接受客户端连接if((new_socketaccept(server_fd, (struct sockaddr *)address, (socklen_t*)addlen))0){perror(accept failed);exit(EXIT_FAILURE);}//读取客户端请求read(new_socket, buffer, BUFFER_SIZE);coutRequest received :\nbufferendl;//解析Http请求//这段代码是解析Http请求中提取 请求方法、路径和Http版本。如下//第一次提取method得到GET//第二次提取path得到/index.html//第三次提取version得到HTTP/1.1std::istringstream request(buffer);std::string method , path , version;requestmethodpathversion;//默认首页if(path/){path/index.html;}//构建文件路径std::string filePath .path;//处理GET请求if(methodGET){if(fileExists(filePath)){//文件存在std::string content readFile(filePath);//读取文件内容std::string contentType getContentType(filePath);//获取文件类型std::ostringstream response; // 构建响应responseHTTP/1.1 200 OK\r\nContent-Type:contentType\r\nContent-Length:content.length()\r\n\r\ncontent;//响应头和响应体responsecontent;//发送响应send(new_socket, response.str().c_str(), response.str().length(), 0);}else{//404 NOT FOUNDstd::string notFoundHTTP/1.1 404 Not Found\r\n\r\n404 Not Found;send(new_socket, notFound.c_str(), notFound.length(), 0);}}else if(methodPOST){//处理POST请求//简单的响应客户端的POST请求可以根据需要解析POST请求std::string responseHTTP/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 notAllowedHTTP/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 langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width,initial-scale1.0title这是一个简单的WebServer/titlestylebody{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
headerh1这是一个简单的WebServer/h1
/header
mainp这是一个简单的WebServer你可以在这里放置一些内容。/pbr/img src23.png altC测试
/main
footerpcopy;2025 My WebServer By HuJiaHang/p
/footer/body
/html三、编译和运行
编译
g -stdc20 WebServer.cpp -o WebServer
//使用C20标准是因为std::string::ends_with()是C20引入的功能运行执行编译好的WebServer程序
./WebServer四、访问测试
使用浏览器访问http//localhost8080可以获取静态HTML页面、CSS样式、JavaScript脚本和图片注意如果使用的是云服务器就必须要在安全组中放开端口以下是我的测试