http协议/http_demo

任务:编写http协议的服务器,用户可以通过浏览器访问,服务器可以相应客户的请求的demo代码

使用手册:./HttpServer port

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(0);
    }
    std::unique_ptr<HttpServer> httpserver(new HttpServer(atoi(argv[1]), HandlerHttpRequest));
    httpserver->Start();
    return 0;
}

// 一般http都要有自己的web根目录
#define ROOT "./wwwroot" // ./wwwroot/index.html
// 如果客户端只请求了一个/,我们返回默认首页
#define HOMEPAGE "index.html"

void HandlerHttpRequest(int sockfd)
{
    // 1. 读取请求 for test
    char buffer[10240]; 	
    ssize_t s = recv(sockfd, buffer, sizeof(buffer) - 1, 0); 从套接字中读取用户请求
    if (s > 0)
    {
        buffer[s] = 0;
}
        std::cout << buffer << "\n--------------------\n"<< std::endl; 
    
    std::vector<std::string> vline;		先通过\n将用户的请求报文切分
    Util::cutString(buffer, "\n", &vline);

    std::vector<std::string> vblock;	把第一行的内容切分,验证请求报文第一行的内容
    Util::cutString(vline[0], " ", &vblock);

    std::string file = vblock[1]; // /a/b/c.html	这是用户要访问的资源的路径
    std::string target = ROOT;	

    if(file == "/") file = "/index.html"; 如果用户请求的是根目录那就把/index.html给用户响应
    //wwwroot/index.html
    //wwwroot/a/b/c.html
    target += file;		构建用户要访问的目标资源的地址
    std::cout << target << std::endl;	

    std::string content;	//打开用户要访问的文件
    std::ifstream in(target);
    if(in.is_open())
    {
        std::string line;
        while(std::getline(in, line))
        {
            content += line;
        }
        in.close();
    }

     std::string HttpResponse;	构建相应报文
     if(content.empty()) HttpResponse= "HTTP/1.1 404 NoFound\r\n"; 没有对应资源路径的情况
     else HttpResponse= "HTTP/1.1 200 OK\r\n"; 有资源
     HttpResponse += "\r\n";	
     HttpResponse += content;
     send(sockfd, HttpResponse.c_str(), HttpResponse.size(), 0); 将报文传给对方的浏览器
}

辅助代码

#pragma once 用于切分字符串,服务器解析用户请求

#include 
#include 

class Util
{
public:
    // aaaa\r\nbbbbb\r\nccc\r\n\r\n
    static void cutString(std::string s, const std::string &sep, std::vector<std::string> *out)
    {
        std::size_t start = 0;
        while (start < s.size())
        {
            auto pos = s.find(sep, start);
            if (pos == std::string::npos) break;
            std::string sub = s.substr(start, pos - start);
            // std::cout << "----" << sub << std::endl;
            out->push_back(sub);
            start += sub.size();
            start += sep.size();
        }
        if(start < s.size()) out->push_back(s.substr(start));
    }
};

使用手册

#pragma once

#include 
#include 

void Usage(std::string proc)
{
    std::cout << "\nUsage: " << proc <<  " port\n" << std::endl;
}

我不会写前端就自动生成一个html啦

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>welcome to mypage</title>
</head>
<body>
    <h3>这个一个Linux study</h3>
    <p>红红火火恍恍惚惚哈哈</p>
    <p>终于弄出来了,一开始不晓得问题在哪里</p>
    <p>我是一个Linux的学习者,我正在进行http的测试工作!!</p>
    <p>请问你是谁呀哈哈哈哈哈哈哈</p>
    <p>学习好难,怎么也学不废,呜呜呜呜,不会算法,菜鸡就要多练</p>
    <p>好烦啊</p>
    <p>不喜欢实验课,不喜欢上学,最讨厌上实验课,课设,去当保安吧,少走40年弯路哦</p>
</body>
</html>

然后试着访问自己的服务器是这样的
http协议/http_demo_第1张图片

你可能感兴趣的:(Linux网络编程,http,网络协议,网络)