国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【計(jì)算機(jī)網(wǎng)絡(luò)】HTTP協(xié)議以及簡(jiǎn)單的HTTP服務(wù)器實(shí)現(xiàn)

這篇具有很好參考價(jià)值的文章主要介紹了【計(jì)算機(jī)網(wǎng)絡(luò)】HTTP協(xié)議以及簡(jiǎn)單的HTTP服務(wù)器實(shí)現(xiàn)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、HTTP協(xié)議

雖然我們說(shuō), 應(yīng)用層協(xié)議是我們程序猿自己定的.

但實(shí)際上, 已經(jīng)有大佬們定義了一些現(xiàn)成的, 又非常好用的應(yīng)用層協(xié)議, 供我們直接參考使用. HTTP(超文本傳輸議)就是其中之一。

1.認(rèn)識(shí)URL

平時(shí)我們俗稱的 “網(wǎng)址” 其實(shí)就是說(shuō)的 URL

【計(jì)算機(jī)網(wǎng)絡(luò)】HTTP協(xié)議以及簡(jiǎn)單的HTTP服務(wù)器實(shí)現(xiàn),Linux網(wǎng)絡(luò)編程,計(jì)算機(jī)網(wǎng)絡(luò),http,服務(wù)器,url,重定向,長(zhǎng)連接,會(huì)話保持

2.urlencode和urldecode

像 / ? : 等這樣的字符, 已經(jīng)被url當(dāng)做特殊意義理解了. 因此這些字符不能隨意出現(xiàn).

比如, 某個(gè)參數(shù)中需要帶有這些特殊字符, 就必須先對(duì)特殊字符進(jìn)行轉(zhuǎn)義.

轉(zhuǎn)義的規(guī)則如下:

將需要轉(zhuǎn)碼的字符轉(zhuǎn)為16進(jìn)制,然后從右到左,取4位(不足4位直接處理),每2位做一位,前面加上%,編成%XY格式

【計(jì)算機(jī)網(wǎng)絡(luò)】HTTP協(xié)議以及簡(jiǎn)單的HTTP服務(wù)器實(shí)現(xiàn),Linux網(wǎng)絡(luò)編程,計(jì)算機(jī)網(wǎng)絡(luò),http,服務(wù)器,url,重定向,長(zhǎng)連接,會(huì)話保持

“+” 被轉(zhuǎn)義成了 “%2B”

urldecode就是urlencode的逆過(guò)程;

encode:對(duì)特殊符號(hào)和漢字編碼為%XX

decode:服務(wù)器(軟件)收到url請(qǐng)求–自己對(duì)特殊%XX進(jìn)行解碼

urldecode工具

3.HTTP協(xié)議格式

HTTP請(qǐng)求

【計(jì)算機(jī)網(wǎng)絡(luò)】HTTP協(xié)議以及簡(jiǎn)單的HTTP服務(wù)器實(shí)現(xiàn),Linux網(wǎng)絡(luò)編程,計(jì)算機(jī)網(wǎng)絡(luò),http,服務(wù)器,url,重定向,長(zhǎng)連接,會(huì)話保持

首行: [方法] + [url] + [版本]

Header: 請(qǐng)求的屬性, 冒號(hào)分割的鍵值對(duì);每組屬性之間使用\n分隔;遇到空行表示Header部分結(jié)束

Body: 空行后面的內(nèi)容都是Body. Body允許為空字符串. 如果Body存在, 則在Header中會(huì)有一個(gè)Content-Length屬性來(lái)標(biāo)識(shí)Body的長(zhǎng)度;

HTTP響應(yīng)

【計(jì)算機(jī)網(wǎng)絡(luò)】HTTP協(xié)議以及簡(jiǎn)單的HTTP服務(wù)器實(shí)現(xiàn),Linux網(wǎng)絡(luò)編程,計(jì)算機(jī)網(wǎng)絡(luò),http,服務(wù)器,url,重定向,長(zhǎng)連接,會(huì)話保持

首行: [版本號(hào)] + [狀態(tài)碼] + [狀態(tài)碼解釋]

Header: 請(qǐng)求的屬性, 冒號(hào)分割的鍵值對(duì);每組屬性之間使用\n分隔;遇到空行表示Header部分結(jié)束

Body: 空行后面的內(nèi)容都是Body. Body允許為空字符串. 如果Body存在, 則在Header中會(huì)有一個(gè)Content-Length屬性來(lái)標(biāo)識(shí)Body的長(zhǎng)度; 如果服務(wù)器返回了一個(gè)html頁(yè)面, 那么html頁(yè)面內(nèi)容就是在body中

狀態(tài)碼有200,400,302,307,500,404等等

狀態(tài)碼描述:404 -> Not Found 200 -> OK

【計(jì)算機(jī)網(wǎng)絡(luò)】HTTP協(xié)議以及簡(jiǎn)單的HTTP服務(wù)器實(shí)現(xiàn),Linux網(wǎng)絡(luò)編程,計(jì)算機(jī)網(wǎng)絡(luò),http,服務(wù)器,url,重定向,長(zhǎng)連接,會(huì)話保持

1.請(qǐng)求和響應(yīng)怎么保證應(yīng)用層完整讀取完畢了?

a.首先讀取完整的一行

b.while(讀取完整的一行)-所有的請(qǐng)求行+請(qǐng)求報(bào)頭全部讀完-直到空行

c.我們能保證把報(bào)頭讀完,報(bào)頭有一個(gè)屬性:Content-Length:XXX正文長(zhǎng)度

d.解析出來(lái)內(nèi)容長(zhǎng)度,再根據(jù)內(nèi)容長(zhǎng)度,讀取正文即可。

2.請(qǐng)求和響應(yīng)是怎么做到序列化和反序列化的?

http自己實(shí)現(xiàn)的,第一行+請(qǐng)求/響應(yīng)報(bào)頭,只要按照\(chéng)r\n將字符串1->n即可,正文則不需要做

響應(yīng)的正文可以是html/css/js/圖片/視頻/音頻等

4.HTTP的方法

【計(jì)算機(jī)網(wǎng)絡(luò)】HTTP協(xié)議以及簡(jiǎn)單的HTTP服務(wù)器實(shí)現(xiàn),Linux網(wǎng)絡(luò)編程,計(jì)算機(jī)網(wǎng)絡(luò),http,服務(wù)器,url,重定向,長(zhǎng)連接,會(huì)話保持

其中最常用的就是GET方法和POST方法.

5.HTTP的狀態(tài)碼

【計(jì)算機(jī)網(wǎng)絡(luò)】HTTP協(xié)議以及簡(jiǎn)單的HTTP服務(wù)器實(shí)現(xiàn),Linux網(wǎng)絡(luò)編程,計(jì)算機(jī)網(wǎng)絡(luò),http,服務(wù)器,url,重定向,長(zhǎng)連接,會(huì)話保持

最常見的狀態(tài)碼, 比如 200(OK), 404(Not Found), 403(Forbidden), 302(Redirect, 重定向), 504(Bad Gateway)

6.HTTP常見Header

Content-Type: 數(shù)據(jù)類型(text/html等)

Content-Length: Body的長(zhǎng)度

Host: 客戶端告知服務(wù)器, 所請(qǐng)求的資源是在哪個(gè)主機(jī)的哪個(gè)端口上;

User-Agent: 聲明用戶的操作系統(tǒng)和瀏覽器版本信息;

referer: 當(dāng)前頁(yè)面是從哪個(gè)頁(yè)面跳轉(zhuǎn)過(guò)來(lái)的;

location: 搭配3xx狀態(tài)碼使用, 告訴客戶端接下來(lái)要去哪里訪問;

Cookie: 用于在客戶端存儲(chǔ)少量信息. 通常用于實(shí)現(xiàn)會(huì)話(session)的功能;

7.重定向

我們使用手機(jī)或者瀏覽器的時(shí)候,屏幕什么也沒有點(diǎn),就跳轉(zhuǎn)到了其他的頁(yè)面,比如自動(dòng)跳轉(zhuǎn)到廣告商等,這是通過(guò)重定向完成的。重定向分為臨時(shí)重定向和永久重定向。

重定向過(guò)程:客戶端向服務(wù)器發(fā)送http請(qǐng)求,服務(wù)器給客戶端發(fā)送的http響應(yīng)的狀態(tài)碼為3XX,附帶一個(gè)新的url,然后客戶端重新向新的服務(wù)器發(fā)起請(qǐng)求—臨時(shí)重定向。假如一個(gè)公司的一個(gè)網(wǎng)站,因?yàn)楦鞣N原因(比如同時(shí)訪問數(shù)量受限等),所以重新寫了一個(gè)網(wǎng)站,但是客戶不知道新的網(wǎng)站鏈接,只知道老的鏈接,所以公司對(duì)老的鏈接進(jìn)行永久重定向,客戶在訪問以前的網(wǎng)站的時(shí)候自動(dòng)跳轉(zhuǎn)到新的網(wǎng)站—永久重定向

【計(jì)算機(jī)網(wǎng)絡(luò)】HTTP協(xié)議以及簡(jiǎn)單的HTTP服務(wù)器實(shí)現(xiàn),Linux網(wǎng)絡(luò)編程,計(jì)算機(jī)網(wǎng)絡(luò),http,服務(wù)器,url,重定向,長(zhǎng)連接,會(huì)話保持

8.長(zhǎng)連接

其實(shí)我們看到的網(wǎng)頁(yè),實(shí)際上可能由多種元素構(gòu)成,即一張完整的網(wǎng)頁(yè)需要多次http請(qǐng)求

http網(wǎng)頁(yè)中可能包含多個(gè)元素,如果頻繁的發(fā)起http請(qǐng)求,http是基于TCP的,TCP是面向連接的,就會(huì)有頻繁創(chuàng)建連接的問題(客戶端和服務(wù)器都需要對(duì)連接進(jìn)行管理,先描述再組織,會(huì)對(duì)連接創(chuàng)建對(duì)應(yīng)的內(nèi)核數(shù)據(jù)結(jié)構(gòu),對(duì)連接的管理就變成了對(duì)數(shù)據(jù)結(jié)構(gòu)的管理,就會(huì)有時(shí)間和空間的成本)

所以就提出了長(zhǎng)連接,長(zhǎng)連接需要client和server都要支持,建立好一條連接,獲取一份資源的時(shí)候,通過(guò)同一條連接來(lái)完成

Connection:Keep-alive  --支持長(zhǎng)連接
Connection:close   --不支持長(zhǎng)連接

9.會(huì)話保持

我們使用網(wǎng)頁(yè)的bilibili的時(shí)候,我們登錄一次之后,后面的一段時(shí)間都不需要我們重新進(jìn)行登錄了,關(guān)閉頁(yè)面,然后重新點(diǎn)進(jìn)去也不需要重新登錄,這就是http的會(huì)話保持做到的

會(huì)話保持嚴(yán)格意義不是http天然具備的,而是后面使用發(fā)現(xiàn)需要的

http協(xié)議是無(wú)狀態(tài)的,即http不關(guān)心上一次和下一次的請(qǐng)求,只負(fù)責(zé)當(dāng)前請(qǐng)求的傳輸,但是用戶需要,因?yàn)橛脩舨榭葱碌木W(wǎng)頁(yè)是常規(guī)操作,如果發(fā)送頁(yè)面跳轉(zhuǎn),那么新的頁(yè)面也就無(wú)法識(shí)別是哪一個(gè)用戶了,為了讓用戶一經(jīng)登錄,可以在整個(gè)網(wǎng)站按照自己的身份進(jìn)行隨意訪問,就需要會(huì)話保持。

我們看騰訊視頻的時(shí)候,對(duì)于需要會(huì)員的視頻,我們可以通過(guò)鏈接直接獲取而不進(jìn)行登錄嗎,答案是不行的,凡是對(duì)網(wǎng)頁(yè)訪問有權(quán)限要求的網(wǎng)頁(yè),在被獲取之前,全部都要做判斷,進(jìn)行身份認(rèn)證。

會(huì)話保持有兩種方法:

第一種方案:我們?cè)跒g覽器進(jìn)行登錄輸入信息之后,瀏覽器會(huì)把我們用戶輸入的信息:用戶名&&密碼保持起來(lái),這個(gè)被稱為cookie數(shù)據(jù)。cookie分為cookie文件級(jí)數(shù)據(jù)和cookie內(nèi)存級(jí)數(shù)據(jù)。往后只要訪問同一個(gè)網(wǎng)站,瀏覽器就會(huì)自動(dòng)推送歷史保留信息給服務(wù)器

我們登錄的時(shí)候,瀏覽器保存了cookie文件,每次請(qǐng)求賬號(hào)密碼都要進(jìn)行推送,然后服務(wù)器再返回資源,但是這里有個(gè)問題,如果黑客在我們的電腦上種植了木馬病毒,獲取了我們的cookie文件,這樣我們的賬號(hào)密碼就泄漏了,那么黑客使用他的瀏覽器登錄我們的賬號(hào),此時(shí)服務(wù)器會(huì)誤認(rèn)為這個(gè)非法用戶是你,如果是QQ,微信對(duì)我們就會(huì)造成很大的影響

第二種方案:我們進(jìn)行登錄的時(shí)候輸入用戶名和密碼,此時(shí)服務(wù)器端會(huì)根據(jù)用戶的信息形成一個(gè)session文件,它有唯一的名稱:session id來(lái)進(jìn)行唯一標(biāo)識(shí),然后將當(dāng)前用戶的session id返回給用戶,此時(shí)瀏覽器的cookie文件中保存的是session id。此后用戶發(fā)送http request 和session id給服務(wù)器,服務(wù)器根據(jù)session id進(jìn)行鑒權(quán),此時(shí)client保存了cookie,server保存了session。

如果黑客獲取了用戶的session,此時(shí)服務(wù)器還是會(huì)誤認(rèn)為這個(gè)非法用戶是你,但是此時(shí)我們已經(jīng)將矛盾轉(zhuǎn)移了,此時(shí)黑客盜取的是公司的私密數(shù)據(jù),有法律進(jìn)行維護(hù),此外還配合了其他的策略來(lái)緩解該類問題,比如我們?cè)诤芏痰臅r(shí)間內(nèi)從一個(gè)地區(qū)到另一個(gè)地區(qū),QQ就會(huì)提醒我們異地登錄,需要重新進(jìn)行登錄等等

10.基本工具

這里介紹兩個(gè)基本工具:postman 和 fiddler
【計(jì)算機(jī)網(wǎng)絡(luò)】HTTP協(xié)議以及簡(jiǎn)單的HTTP服務(wù)器實(shí)現(xiàn),Linux網(wǎng)絡(luò)編程,計(jì)算機(jī)網(wǎng)絡(luò),http,服務(wù)器,url,重定向,長(zhǎng)連接,會(huì)話保持

postman不是抓包工具,而是一個(gè)模擬客戶端—瀏覽器的行為的工具

fiddler是一個(gè)抓包工具,http工具

postman和fiddler的原理:

瀏覽器將請(qǐng)求發(fā)送給fiddler,此時(shí)fiddler可以作為代理服務(wù)器看待,然后就fiddler將請(qǐng)求轉(zhuǎn)發(fā)給服務(wù)器,服務(wù)器響應(yīng)的信息通過(guò)fiddler轉(zhuǎn)發(fā)到用戶的手中,而postman則就是相當(dāng)于客戶端向服務(wù)器發(fā)起請(qǐng)求

我們對(duì)下文的程序進(jìn)行抓包:

我們可以看到,我們的賬號(hào)和密碼都是明文的,所以POST和GET都是不安全的,只有是否私密的區(qū)別,安全需要HTTPS來(lái)完成。

二、簡(jiǎn)單的HTTP服務(wù)器實(shí)現(xiàn)

1.err.hpp

#pragma once

enum
{
    USAGE_ERR = 1,
    SOCKET_ERR,
    BIND_ERR,
    LISTEN_ERR
};

2.log.hpp

#pragma once

#include <iostream>
#include <string>
#include <cstdarg>
#include <ctime>
#include <unistd.h>

#define DEBUG 0
#define NORMAL 1
#define WARNING 2
#define ERROR 3
#define FATAL 4

#define LOG_NORMAL "log.txt"
#define LOG_ERR "log.error"

#define NUM 1024

const char *to_levelstr(int level)
{
    switch (level)
    {
    case DEBUG:
        return "DEBUG";
    case NORMAL:
        return "NORMAL";
    case WARNING:
        return "WARNING";
    case ERROR:
        return "ERROR";
    case FATAL:
        return "FATAL";
    default:
        return nullptr;
    }
}

void logMessage(int level, const char *format, ...)
{

    char logprefix[NUM];
    snprintf(logprefix, sizeof(logprefix), "[%s][%ld][pid: %d]",
             to_levelstr(level), (long int)time(nullptr), getpid());

    char logcontent[NUM];
    va_list arg;
    va_start(arg, format);
    vsnprintf(logcontent, sizeof(logcontent), format, arg);

    std::cout << logprefix << logcontent << std::endl;

    FILE *log = fopen(LOG_NORMAL, "a");
    FILE *error = fopen(LOG_ERR, "a");

    if (log && error)
    {
        FILE *cur = nullptr;
        if (level == DEBUG || level == NORMAL || level == WARNING)
            cur = log;
        if (level == ERROR || level == FATAL)
            cur = error;
        if (cur)
            fprintf(cur, "%s%s\n", logprefix, logcontent);
        fclose(log);
        fclose(error);
    }
}

3.procotol.hpp

#pragma once

#include <iostream>
#include <string>
#include <sstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "Util.hpp"

const std::string sep = "\r\n";
const std::string default_root = "./wwwroot";
const std::string home_page = "index.html";
const std::string html_404 = "wwwroot/404.html";

class HttpRequest
{
public:
    HttpRequest() {}
    ~HttpRequest() {}

public:
    void parse()
    {
        // 1. 從inbuffer中拿到第一行,分隔符\r\n
        std::string line = Util::getOneLine(inbuffer, sep);
        if (line.empty())
            return;
        // 2. 從請(qǐng)求行中提取三個(gè)字段
        // std::cout << "line: " << line << std::endl;
        std::stringstream ss(line);
        ss >> method >> url >> httpversion;

        // 3. 添加web默認(rèn)路徑
        path = default_root; // ./wwwroot,
        path += url;         //./wwwroot/a/b/c.html, ./wwwroot/
        if (path[path.size() - 1] == '/')
            path += home_page;

        // 4.獲取path對(duì)應(yīng)資源的后綴
        // ./wwwroot.index.html
        // ./wwwroot.1.jpg
        auto pos = path.rfind(".");
        if (pos == std::string::npos)
            suffix = ".html";
        else
            suffix = path.substr(pos);

        // 5.得到資源的大小
        struct stat st;
        int n = stat(path.c_str(), &st);
        if (n == 0)
            size = st.st_size;
        else
            size = -1;
    }

public:
    std::string inbuffer;

    std::string method;
    std::string url;
    std::string httpversion;
    std::string path;
    std::string suffix;
    int size;
};

class HttpResponse
{
public:
    std::string outbuffer;
};

4.Sock.hpp

#pragma once

#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "log.hpp"
#include "err.hpp"

static const int backlog = 5;

class Sock
{
public:
    void Socket()
    {
        _listensock = socket(AF_INET, SOCK_STREAM, 0);
        if (_listensock < 0)
        {
            logMessage(FATAL, "create socket error");
            exit(SOCKET_ERR);
        }

        int opt = 1;
        setsockopt(_listensock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof opt);
        logMessage(NORMAL, "create socket success");
    }

    void Bind(const uint16_t &port)
    {
        struct sockaddr_in local;
        memset(&local, 0, sizeof local);

        local.sin_family = AF_INET;
        local.sin_addr.s_addr = INADDR_ANY;
        local.sin_port = htons(port);

        int n = bind(_listensock, (struct sockaddr *)&local, sizeof local);
        if (n < 0)
        {
            logMessage(FATAL, "bind socket error");
            exit(BIND_ERR);
        }
        logMessage(NORMAL, "bind socket success");
    }

    void Listen()
    {
        int n = listen(_listensock, backlog);
        if (n < 0)
        {
            logMessage(FATAL, "listen socket error");
            exit(LISTEN_ERR);
        }

        logMessage(NORMAL, "listen socket success");
    }

    int Accept()
    {
        struct sockaddr_in peer;

        socklen_t len = sizeof(peer);
        int sock = accept(_listensock, (struct sockaddr *)&peer, &len);

        return sock;
    }

    int Fd()
    {
        return _listensock;
    }

    void Close()
    {
        if (_listensock > 0)
            close(_listensock);
    }

private:
    int _listensock;
};

5.Util.hpp

#pragma once

#include <string>
#include <fstream>

class Util
{
public:
    static std::string getOneLine(std::string &buffer, const std::string &sep)
    {
        auto pos = buffer.find(sep);
        if (pos == std::string::npos)
            return "";
        std::string sub = buffer.substr(0, pos);
        buffer.erase(0, sub.size() + sep.size());
        return sub;
    }

    static bool readFile(const std::string resource, char *buffer, int size)
    {
        std::ifstream in(resource, std::ios::binary);
        if (!in.is_open())
            return false;

        in.read(buffer, size);

        in.close();
        return true;
    }
};

6.httpServer.hpp

#pragma once 

#include <functional>
#include <sys/wait.h>
#include "Sock.hpp"
#include "protocol.hpp"
#include "log.hpp"
#include "err.hpp"
#include "Util.hpp"

namespace server
{
    static const int defaultport = 8080;

    using func_t = std::function<bool(const HttpRequest &, HttpResponse &)>;

    class httpServer
    {
    public:
        httpServer(const func_t func, const uint16_t &port = defaultport)
            : _func(func), _port(port)
        {
        }

        void initServer()
        {
            _sock.Socket();
            _sock.Bind(_port);
            _sock.Listen();
        }

        void handlerEvent(int sock)
        {
            // 1. 讀到完整的http請(qǐng)求
            // 2. 反序列化
            // 3. httprequst, httpresponse, _func(req, resp)
            // 4. resp序列化
            // 5. send
            char buffer[4096];
            HttpRequest req;
            HttpResponse resp;
            size_t n = recv(sock, buffer, sizeof(buffer) - 1, 0);
            if (n > 0)
            {
                buffer[n] = 0;
                req.inbuffer = buffer;
                req.parse();
                _func(req, resp); // req -> resp
                send(sock, resp.outbuffer.c_str(), resp.outbuffer.size(), 0);
            }
        }

        void start()
        {
            for (;;)
            {
                int sock = _sock.Accept();
                if (sock < 0)
                    continue;

                pid_t id = fork();
                if (id == 0)
                {
                    _sock.Close();
                    if (fork() > 0)
                        exit(0);
                    handlerEvent(sock);
                    close(sock);
                    exit(0);
                }
                close(sock);

                waitpid(id, nullptr, 0);
            }
        }

        ~httpServer()
        {
        }

    private:
        Sock _sock;
        uint16_t _port;
        func_t _func;
    };
}

7.httpServer.cc

#include "httpServer.hpp"
#include <memory>

using namespace std;
using namespace server;

void Usage(std::string proc)
{
    cerr << "Usage:\n\t" << proc << " port\r\n\r\n";
}

std::string suffixToDesc(const std::string suffix)
{
    std::string ct = "Content-Type: ";
    if (suffix == ".html")
        ct += "text/html";
    else if (suffix == ".jpg")
        ct += "application/x-jpg";
    ct += "\r\n";
    return ct;
}

// 1. 服務(wù)器和網(wǎng)頁(yè)分離,html
// 2. url -> / : web根目錄
bool Get(const HttpRequest &req, HttpResponse &resp)
{
    // for test
    cout << "----------------------http start---------------------------" << endl;
    cout << req.inbuffer;
    std::cout << "method: " << req.method << std::endl;
    std::cout << "url: " << req.url << std::endl;
    std::cout << "httpversion: " << req.httpversion << std::endl;
    std::cout << "path: " << req.path << std::endl;
    std::cout << "suffix: " << req.suffix << std::endl;
    std::cout << "size: " << req.size << "字節(jié)" << std::endl;
    cout << "----------------------http end---------------------------" << endl;

    // std::string respline = "HTTP/1.1 200 OK\r\n";
    std::string respline = "HTTP/1.1 307 Permanent Redirect\r\n";
    std::string respheader = suffixToDesc(req.suffix);

    respheader += "Location: https://www.qq.com/\r\n";
    std::string respblank = "\r\n";
    // std::string body = "<html lang=\"en\"><head><meta charset=\"UTF-8\"><title>for test</title><h1>hello world</h1></head><body><p>多情只有春庭月,猶為離人照落花</p></body></html>";

    std::string body;
    body.resize(req.size + 1);
    if (!Util::readFile(req.path, (char *)body.c_str(), req.size))
    {
        Util::readFile(html_404, (char *)body.c_str(), req.size);
    }

    respheader += "Content-Length: ";
    respheader += to_string(body.size());
    respheader += "\r\n";

    resp.outbuffer += respline;
    resp.outbuffer += respheader;
    resp.outbuffer += respblank;

    cout << "----------------------http response start---------------------------" << endl;
    std::cout << "resp.outbuffer" << resp.outbuffer << std::endl;
    cout << "----------------------http response end---------------------------" << endl;
    resp.outbuffer += body;

    return true;
}

// ./httpServer port
int main(int argc, char *argv[])
{
    // if(argc != 2)
    // {
    //     Usage(argv[0]);
    //     exit(0);
    // }
    // uint16_t port = atoi(argv[1]);
    // unique_ptr<httpServer> httpsvr(new httpServer(Get, port));

    unique_ptr<httpServer> httpsvr(new httpServer(Get));
    httpsvr->initServer();
    httpsvr->start();

    return 0;
}

8.總結(jié)分析

一個(gè)用戶看到的網(wǎng)頁(yè)結(jié)果,可能是多個(gè)資源結(jié)合而成的,所以要獲取一個(gè)網(wǎng)頁(yè)效果,我們的瀏覽器一定會(huì) 發(fā)起多次http請(qǐng)求。

我們進(jìn)行數(shù)據(jù)提交的時(shí)候,本質(zhì)前端要通過(guò)form表單提交的,瀏覽器會(huì)自動(dòng)將form表單中的內(nèi)容轉(zhuǎn)換成GET/POST方法請(qǐng)求

GET和POST的區(qū)別

如下是GET的方式

【計(jì)算機(jī)網(wǎng)絡(luò)】HTTP協(xié)議以及簡(jiǎn)單的HTTP服務(wù)器實(shí)現(xiàn),Linux網(wǎng)絡(luò)編程,計(jì)算機(jī)網(wǎng)絡(luò),http,服務(wù)器,url,重定向,長(zhǎng)連接,會(huì)話保持

如下是POST的方式

【計(jì)算機(jī)網(wǎng)絡(luò)】HTTP協(xié)議以及簡(jiǎn)單的HTTP服務(wù)器實(shí)現(xiàn),Linux網(wǎng)絡(luò)編程,計(jì)算機(jī)網(wǎng)絡(luò),http,服務(wù)器,url,重定向,長(zhǎng)連接,會(huì)話保持

二者的區(qū)別如下:

GET通過(guò)URL傳遞參數(shù),具體:http://ip:port/XXX/YYY?name=value&name1=value1

POST提交參數(shù)通過(guò)http請(qǐng)求的正文提交參數(shù)

POST方法通過(guò)正文的提交參數(shù),所以一般用戶看不到,私密性更好,私密性 != 安全性,GET方法不私密

無(wú)論是GET還是POST方法,都不安全,要談安全,必須加密 --https

通過(guò)URL傳遞參數(shù),注定了不能太大

但是POST方法,通過(guò)正文,正文可以很大,甚至可以是其他的東西文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-807731.html

到了這里,關(guān)于【計(jì)算機(jī)網(wǎng)絡(luò)】HTTP協(xié)議以及簡(jiǎn)單的HTTP服務(wù)器實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • [計(jì)算機(jī)網(wǎng)絡(luò)]---Http協(xié)議

    [計(jì)算機(jī)網(wǎng)絡(luò)]---Http協(xié)議

    前言 作者 :小蝸牛向前沖 名言 :我可以接受失敗,但我不能接受放棄 ??如果覺的博主的文章還不錯(cuò)的話,還請(qǐng) 點(diǎn)贊,收藏,關(guān)注??支持博主。如果發(fā)現(xiàn)有問題的地方歡迎?大家在評(píng)論區(qū)指正? 本期學(xué)習(xí):htpp協(xié)議,認(rèn)識(shí)URL,?理解htpp協(xié)議的基本結(jié)構(gòu),寫一個(gè)簡(jiǎn)單的http協(xié)議。

    2024年02月19日
    瀏覽(26)
  • 計(jì)算機(jī)網(wǎng)絡(luò)(5) --- http協(xié)議

    計(jì)算機(jī)網(wǎng)絡(luò)(5) --- http協(xié)議

    計(jì)算機(jī)網(wǎng)絡(luò)(4) --- 協(xié)議定制_哈里沃克的博客-CSDN博客 協(xié)議定制 https://blog.csdn.net/m0_63488627/article/details/132070683?spm=1001.2014.3001.5501 目錄 1.http協(xié)議介紹 1.協(xié)議的延申 2.http協(xié)議介紹 3.URL 4.urlencode和urldecode 2.HTTP協(xié)議結(jié)構(gòu) 1.引入 2.細(xì)節(jié) 3.HTTP協(xié)議的使用 1.協(xié)議 2.網(wǎng)頁(yè)配置 3.HTTP請(qǐng)求方法

    2024年02月14日
    瀏覽(28)
  • 【計(jì)算機(jī)網(wǎng)絡(luò)】應(yīng)用層協(xié)議 -- HTTP協(xié)議

    【計(jì)算機(jī)網(wǎng)絡(luò)】應(yīng)用層協(xié)議 -- HTTP協(xié)議

    協(xié)議。網(wǎng)絡(luò)協(xié)議的簡(jiǎn)稱,網(wǎng)絡(luò)協(xié)議是通信計(jì)算機(jī)雙方必須共同遵守的一組約定,比如怎么建立連接,怎么互相識(shí)別等。 為了使數(shù)據(jù)在網(wǎng)絡(luò)上能夠從源頭到達(dá)目的,網(wǎng)絡(luò)通信的參與方必須遵守相同的規(guī)則,我們稱這套相同的規(guī)則為協(xié)議(protocol),而協(xié)議最終都需要通過(guò)計(jì)算機(jī)

    2024年02月15日
    瀏覽(27)
  • 計(jì)算機(jī)網(wǎng)絡(luò) - http協(xié)議 與 https協(xié)議(2)

    計(jì)算機(jī)網(wǎng)絡(luò) - http協(xié)議 與 https協(xié)議(2)

    本篇介紹了構(gòu)造http請(qǐng)求的的五種方式,簡(jiǎn)單的使用postman構(gòu)造http請(qǐng)求,進(jìn)一步了解https, 學(xué)習(xí)https的加密過(guò)程,了解對(duì)稱密鑰與非對(duì)稱密鑰對(duì)于加密是如何進(jìn)行的,如有錯(cuò)誤,請(qǐng)?jiān)谠u(píng)論區(qū)指正,讓我們一起交流,共同進(jìn)步! 本文開始 1) 直接在瀏覽器中的地址欄中輸入一個(gè) u

    2024年02月13日
    瀏覽(30)
  • 計(jì)算機(jī)網(wǎng)絡(luò)學(xué)習(xí)day02|HTTP協(xié)議

    計(jì)算機(jī)網(wǎng)絡(luò)學(xué)習(xí)day02|HTTP協(xié)議

    目錄 一、HTTP報(bào)文格式長(zhǎng)什么樣?是如何分割的? 請(qǐng)求行 狀態(tài)行 頭部字段 常用頭字段 小結(jié) 二、HTTP提供了哪些方法?GET和POST的區(qū)別是什么? 1.HTTP有哪些方法 2.GET/HEAD 3.PSOT/PUT 小結(jié) 三、URI和URL URI 的格式 URI 的基本組成 URI 的查詢參數(shù) 小結(jié) 四、HTTP有哪些狀態(tài)碼?分別代表什

    2024年04月23日
    瀏覽(24)
  • 【計(jì)算機(jī)網(wǎng)絡(luò)】應(yīng)用層——HTTP 協(xié)議(一)

    【計(jì)算機(jī)網(wǎng)絡(luò)】應(yīng)用層——HTTP 協(xié)議(一)

    個(gè)人主頁(yè):兜里有顆棉花糖 歡迎 點(diǎn)贊?? 收藏? 留言? 加關(guān)注??本文由 兜里有顆棉花糖 原創(chuàng) 收錄于專欄【網(wǎng)絡(luò)編程】 本專欄旨在分享學(xué)習(xí)計(jì)算機(jī)網(wǎng)絡(luò)的一點(diǎn)學(xué)習(xí)心得,歡迎大家在評(píng)論區(qū)交流討論?? HTTP協(xié)議全稱超文本傳輸協(xié)議,通過(guò)瀏覽器和服務(wù)器進(jìn)行數(shù)據(jù)交互,進(jìn)行

    2024年01月23日
    瀏覽(29)
  • Linux 計(jì)算機(jī)網(wǎng)絡(luò) 深入理解HTTP協(xié)議

    Linux 計(jì)算機(jī)網(wǎng)絡(luò) 深入理解HTTP協(xié)議

    HTTP是超文本傳輸協(xié)議,是用于從萬(wàn)維網(wǎng)服務(wù)器傳輸超文本到本地瀏覽器的傳送協(xié)議。下面就來(lái)介紹HTTP的組成與特性。 HTTP是 ?連接 , ?狀態(tài) , ?作在應(yīng)?層 的協(xié)議。 ?連接: http協(xié)議本身是沒有維護(hù)連接信息的, http的數(shù)據(jù)會(huì)交給?絡(luò)協(xié)議棧傳輸層的TCP協(xié)議, ?TCP是?向

    2024年02月14日
    瀏覽(26)
  • 計(jì)算機(jī)網(wǎng)絡(luò)實(shí)驗(yàn)4:HTTP、DNS協(xié)議分析

    計(jì)算機(jī)網(wǎng)絡(luò)實(shí)驗(yàn)4:HTTP、DNS協(xié)議分析

    實(shí)驗(yàn)內(nèi)容 :使用Wireshark捕獲數(shù)據(jù)包,根據(jù)捕獲的相關(guān)數(shù)據(jù)包分別對(duì)HTTP、DNS協(xié)議展開分析。 額外內(nèi)容 :利用fiddler軟件對(duì)HTTPS協(xié)議進(jìn)行分析。 所需學(xué)時(shí) :1。 重難點(diǎn) :HTTP和DNS協(xié)議的報(bào)文結(jié)構(gòu)。 周次 :第3周。 教材相關(guān)章節(jié) :2.4、2.7。 HTTP(超文本傳輸協(xié)議)是一個(gè)基于 請(qǐng)求與

    2024年02月13日
    瀏覽(23)
  • 計(jì)算機(jī)網(wǎng)絡(luò) - 應(yīng)用層http協(xié)議 - http報(bào)文格式介紹(1)

    計(jì)算機(jī)網(wǎng)絡(luò) - 應(yīng)用層http協(xié)議 - http報(bào)文格式介紹(1)

    本篇認(rèn)識(shí)和理解應(yīng)用層中的http協(xié)議,了解抓包工具并進(jìn)行使用,認(rèn)識(shí)請(qǐng)求報(bào)文與響應(yīng)報(bào)文,了解報(bào)文中基本鍵值對(duì)意思例如:Set-Cookie, 狀態(tài)碼等,如有錯(cuò)誤,請(qǐng)?jiān)谠u(píng)論區(qū)指正,讓我們一起交流,共同進(jìn)步! 本文開始 ① 根據(jù)輸入的url,在域名系統(tǒng)DNS中進(jìn)行解析獲取對(duì)應(yīng)的服務(wù)

    2024年02月12日
    瀏覽(94)
  • 【計(jì)算機(jī)網(wǎng)絡(luò)】| Http.*協(xié)議該知道的那些事兒 | 面經(jīng)

    【計(jì)算機(jī)網(wǎng)絡(luò)】| Http.*協(xié)議該知道的那些事兒 | 面經(jīng)

    本文章參考了很多文檔文獻(xiàn)整理成獅子自己喜歡的風(fēng)格類型文字,主要有: 《圖解網(wǎng)絡(luò)-小林coding》、Github上面的《前端語(yǔ)音社群》,ChatGpt 3.5 大家有興趣可以去找來(lái)看看,一起上岸?。。?主要抓住三方面: 超文本 傳輸 協(xié)議 HTTP 協(xié)議是?個(gè) 雙向協(xié)議 (兩點(diǎn)之間) eg: 瀏覽

    2024年02月05日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包