湖南做網(wǎng)站 要上磐石網(wǎng)絡(luò)seo網(wǎng)站有哪些
文章目錄
- 一、基本概念
- 1.HTTP
- 2.域名
- 3.默認端口號
- 4.URL
- 二、請求與響應(yīng)
- 1.抓包工具
- 2.基本框架
- 3.簡易實現(xiàn)
- 3.1 HttpServer
- 3.2 HttpRequest
- 3.2.1 version1
- 3.2.2 version2
- 3.2.3 version3
- 總結(jié)
- 尾序
一、基本概念
- 常見的應(yīng)用層協(xié)議:
- HTTPS (
H
yperT
extT
ransferP
rotocolS
ecure),安全
的超文本傳輸數(shù)據(jù)。- FTP(
F
ileT
ransferP
rotocol) ,網(wǎng)絡(luò)之間的文件
傳輸。- SMTP(
S
impleM
ailT
ransferP
rotocol),郵件
傳輸。- DNS(
D
omainN
ameS
ystem),域名
解析。- SSH(
S
ecureSH
ell),加密的遠程登錄
會話。
- 一般來講,大多數(shù)情況用現(xiàn)成的應(yīng)用層協(xié)議即可,但是如果做游戲引擎,或者做一些比較私密,對安全性要求很高的項目時,可能需要內(nèi)部指定自定義協(xié)議。
1.HTTP
- HTTP(
H
yperT
extT
ransferP
rotocol)是一種用于傳輸超文本數(shù)據(jù)的應(yīng)用層協(xié)議
。 - 應(yīng)用于Web服務(wù)器與Web瀏覽器之間進行通信。
- 明文傳輸(可能會暴露個人隱私數(shù)據(jù)),因此不安全,但是簡單易用,被廣泛支持。
- 對于HTTP的不安全,之后發(fā)展出了HTTPS,即" 安全的HTTP "。
瀏覽器簡介:
- 瀏覽器簡單來看就是處理數(shù)據(jù)的一種工具,瀏覽器可以解析一些常用的應(yīng)用層協(xié)議的數(shù)據(jù),通過相應(yīng)的連接方式向服務(wù)端發(fā)送請求,接收響應(yīng)并將文件給我們以相應(yīng)的格式呈現(xiàn)出來,具體如何呈現(xiàn)出一個完美的網(wǎng)頁,則是前端開發(fā)人員的工作了,接下來的內(nèi)容我們會制作一個簡單的網(wǎng)頁 ~
- 市面上的瀏覽器多種多樣,因為掌握了瀏覽器,也就掌握了進入網(wǎng)絡(luò)的通道,因此各大公司在早期為了發(fā)展,爭相競爭推動了瀏覽器技術(shù)的發(fā)展,發(fā)展出了成熟的瀏覽器,目前瀏覽器呈現(xiàn)的一般都是跟搜索引擎相結(jié)合的模式,通過搜索網(wǎng)址和關(guān)鍵詞,從而使用戶進入目標網(wǎng)站。
- 現(xiàn)在由于ChatGpt的出現(xiàn)讓信息可以通過對話的形式體現(xiàn),相比搜索引擎的關(guān)鍵詞搜索更加的便利,讓我們獲取知識的成本降低了不少,博主也推薦使用ChatGpt之類的工具來提高學(xué)習(xí)效率。
2.域名
?通過 www.baidu.com,我們可以很明顯的辨認出這是百度的網(wǎng)址,其實這就是百度的域名,那我們再來看39.156.66.14,這里你可能會感覺有點懵逼,其實這也是百度的網(wǎng)址,不信博主復(fù)制粘貼到瀏覽器去訪問一下,下面截圖為證:
這一串?dāng)?shù)字是怎么得到的呢?
-
按下
win + r
,輸入cmd
,按下回車。—— windows系統(tǒng)下 -
在命令窗口輸入
ping www.baidu.com
?這其實是百度的IP地址,通過它,我們就可以定位唯 一 一 臺主機
,進而訪問百度的服務(wù)器,獲取相應(yīng)的首頁資源。此時我們再回到討論的話題,域名相比ip地址,用戶記憶的成本更低,這就是域名的好處
,但從專業(yè)的角度來看,域名背后其實綁定了ip地址,而且可能還不止一個
,如果你ping的ip地址跟我的不一樣,就證明了這一點。
3.默認端口號
常見的默認端口號有:
- HTTP: 80
- HTTPS: 443
- FTP: 21
- SSH: 22
- Telnet: 23
- SMTP: 25
- POP3: 110
- IMAP: 143
- DNS: 53
- 端口號所在文件:
/etc/services
這些端口號一般是不允許被修改的,就像110在我們的腦中已經(jīng)跟報警電話已經(jīng)聯(lián)系了起來,80就是http協(xié)議的默認端口,而且這些端口號在訪問時一般瀏覽器是忽略的,如果改了還得在后面跟上: + 修改的端口號
,因為單憑ip地址只能鎖定一臺主機,還得指定端口號與相應(yīng)的進程才能進行聯(lián)系
,因為網(wǎng)絡(luò)的本質(zhì)就是進程間通信
。
4.URL
- 概念
- URL(
U
niformR
esourceL
ocator)是統(tǒng)一資源定位符的縮寫,用于指定互聯(lián)網(wǎng)上資源的位置和訪問方式。簡單的理解其實就是網(wǎng)址。
- URL(
- 組成
圖解:
- 例1:ssh登錄
- 例二:http協(xié)議
下面我們于查詢字符串和片段標識符舉兩個例子:
- 字符串查詢:
搜索引擎上輸入
C++##
等帶特殊字符的關(guān)鍵詞。查看URL的查詢參數(shù):
- 如下圖:
- 可見這些特殊字符是被編碼了的,不過網(wǎng)上有現(xiàn)成的urlencode解碼工具,進去將此字符串復(fù)制進行轉(zhuǎn)換,可以查看到我們原來的查詢的關(guān)鍵詞。
- 如下圖:
- 因此我們可以簡單的理解查詢不只是簡單的查詢,還要經(jīng)過編碼,從而
避免與網(wǎng)址的符號進行沖突
。
- 片段標識符:
- 當(dāng)我們想要在網(wǎng)址中定位某一個網(wǎng)頁的位置時,需要通過片段標識符。
- 博主上一篇文章的網(wǎng)址 :
https://blog.csdn.net/Shun_Hua/article/details/136523510?spm=1001.2014.3001.5501
。后面跟上和不跟上#_729
,對比效果即可明白片段標識符的作用。
如何找到片段標識符呢?
- 在網(wǎng)頁中右鍵,選擇選項中的檢查。查看網(wǎng)頁源代碼。
- 按下
ctrl + f
在搜索框 搜索id
這個標簽。
- 例:
- 鼠標移動至此,可在網(wǎng)頁上看到對應(yīng)的效果,即標記位置信息。
二、請求與響應(yīng)
1.抓包工具
- fiddler,需要輸入認證信息之后才可進行下載。
- postman, 外網(wǎng)的訪問會有些慢,需要使用魔法,或許訪問不上。
- apifox,國內(nèi)的比較好用。
2.基本框架
我們先使用telnet工具進行簡單的HTTP請求,查看請求與響應(yīng)的格式:
因此可以大致列出請求與響應(yīng)的基本框架:
穿插知識:
- 短連接:瀏覽器通常建立連接只能發(fā)一個請求,然后收一個響應(yīng),之后斷開連接。若想再發(fā)送一個請求,只能再次申請連接,這適用于
無需多數(shù)據(jù)傳輸,無需保持連接,Http/1.0采用的是短連接
。- 長連接:瀏覽器通常建立連接之后會保持一段時間,直接可以進行多次數(shù)據(jù)的傳輸,可以一次發(fā)送多個請求,接收多個響應(yīng),在無數(shù)據(jù)傳輸之后會斷開連接。相比短連接減少因頻繁建立和關(guān)閉連接而產(chǎn)生的額外開銷,提高通信效率,尤其
適用于需要頻繁交換數(shù)據(jù)的場景,Http/1.1版本支持長連接
。- 說明:在請求報頭中如果有
Connection: keep-alive
,則意味申請長連接,申請成功時,會在響應(yīng)報頭處添加:Connection: keep-alive
。
3.簡易實現(xiàn)
?在簡易的了解Http的請求和響應(yīng)的框架之后,我們可以通過代碼,編寫一個簡單的Http服務(wù)器,并且制作一個簡單的網(wǎng)頁,來逐步理解Http的請求和響應(yīng)。
3.1 HttpServer
在之前的文章,我們實現(xiàn)過守護進程,日志,封裝基于TCP的socket等小組件,下面避免代碼冗余就不再給出,下面的HttpServer其實就是一個基于TCP協(xié)議的服務(wù)端,寫多了不管什么類型的服務(wù)端就是一種套路:
- 隨機綁定端口與IP地址進行初始化。
- 對服務(wù)端進行初始化,即創(chuàng)建,綁定,監(jiān)聽套接字。
- 啟動服務(wù)端,接收請求,建立鏈接,提供服務(wù)。
- 提供服務(wù),其實就是將接收信息并對信息進行處理并返回。
關(guān)鍵就在于這個處理邏輯,按照什么方式處理,就決定了服務(wù)端是什么類型的。
- 實現(xiàn)代碼:
#pragma once
#include<iostream>
#include<fstream>
#include<functional>
//容器
#include<vector>
#include<unordered_map>
//網(wǎng)絡(luò)接口
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>//小組件
#include "../Tools/Log.hpp"
#include "../Tools/Socket.hpp"
using cal_t = function<string(string&)>;
string default_ip = "0.0.0.0";
uint16_t default_port = 8080;
class HttpServer;
struct PthreadData
{PthreadData(int sockfd,HttpServer* hsp):fd(sockfd),hp(hsp){}int fd;HttpServer* hp;
};
class HttpServer
{
public:HttpServer(uint16_t port = default_port,\cal_t signal = nullptr,string ip = default_ip):_sockfd(port,ip){}void Init(){_sockfd.Socket();//使端口號可以重復(fù)被使用,之后的TCP內(nèi)容中會詳談。int opt = 1;setsockopt(_sockfd.GetSocket(),SOL_SOCKET,\SO_REUSEADDR|SO_REUSEPORT\,&opt,sizeof(opt));_sockfd.Bind();_sockfd.Listen();}static void *Routine(void* args){pthread_detach(pthread_self());auto thp = static_cast<PthreadData*>(args);HttpServer* hp = thp->hp;int fd = thp->fd;hp->Server(fd);return nullptr;}void Run(){for(;;){sockaddr_in client;socklen_t len;int fd = _sockfd.Accept(&client,&len);pthread_t tid;pthread_create(&tid,nullptr,Routine\,new PthreadData(fd,this));}}void Server(int fd){string mes;for(;;){mes += _sockfd.Read(fd);if(mes == "") break;//處理信息string echo_mes = cal(mes);int num = _sockfd.Write(fd,echo_mes);if(num == 0) break;}_sockfd.Close(fd);}
private:Sock _sockfd;cal_t cal;
};
3.2 HttpRequest
如下是我們實現(xiàn)處理請求類的宏觀框架,讀者有個大致的認識即可,博主下面會分別行進行實現(xiàn),逐一進行講解。
- 實現(xiàn)代碼:
struct HttpRequest
{ //構(gòu)造函數(shù)。HttpRequest();//從請求中獲取一個完整的報文string InCode(string& str);//從報文中將請求的信息進行打散。bool Deserialize(string& str);//對請求報頭解析并獲取對應(yīng)的內(nèi)容。void Prase()//從指定目錄中讀取相關(guān)消息并進行返回。string ReadFromFile(const string& path)//獲取返回網(wǎng)絡(luò)的文件的類型。string GetContentType()//解析URL獲取對應(yīng)的網(wǎng)絡(luò)資源。string GetSourse();//處理服務(wù)器收到的請求。string HanderHttpMes(string &mes);
public://正文之前的部分vector<string> infors;//提供文件在網(wǎng)絡(luò)中的類型。unordered_map<string,string> content_type;//請求方法,大多數(shù)為POST和GET方法。string Method;//統(tǒng)一資源定位符。string Url;//URL里面可能有讀取文件信息,請求的都是網(wǎng)頁文件。string suffix = ".html";//HTTP的版本,一般為1.1或者1.0的。string Version; //請求正文,一般來說響應(yīng)是沒有的。string content;//獲取資源在服務(wù)器的路徑,即根目錄。const string root = "./wwwroot";
};
- 主程序:
#include<iostream>
#include<memory>#include "httpserver.hpp"void Usage(char* pragma_name)
{cout << endl << "Usage: " << pragma_name \<< " + port[8000-8888]" << endl << endl;
}
int main(int argc,char* argv[])
{if(argc != 2){Usage(argv[0]);return 1;}uint16_t port = stoi(argv[1]);HttpRequest req;std::unique_ptr<HttpServer> htp(new HttpServer(port,\bind(&HttpRequest::HanderHttpMes,&req,placeholders::_1)));//bind函數(shù):指定類域,固定this指針,以及參數(shù),從而封裝//出了一個返回值為string類型,參數(shù)為string&的函數(shù)。htp->Init();htp->Run();return 0;
}
- 對請求的處理和程序的運行有了宏觀的認識之后,下面我們先來編寫一段代碼,在網(wǎng)頁中打印出簡單的消息。
- HanderHttpMes的實現(xiàn):
3.2.1 version1
version1:打印出簡單的信息。
string HanderHttpMes(string &mes){//避免mes過長,我們將其清空。mes = "";//空行string empty_line = "\r\n"; //狀態(tài)行string state_line = "HTTP/1.1 200 OK\r\n";//正文string text = "hello world\r\n"; //報文段string package_line = "Content-Length: " +\to_string(text.size()) + empty_line;//響應(yīng)string response = state_line + package_line +\empty_line + text;return response;}
- 運行結(jié)果:
- 效果:
看到效果之后,我們便可大致明白,瀏覽器其實就是接收信息的客戶端,并按照自定義協(xié)議將信息給上層用戶進行呈現(xiàn)。
運用知識:
Content-Length:【空格】【正文段長度】【\r\n】
—— 狀態(tài)行信息,用于瀏覽器的獲取正文段數(shù)據(jù),并按照指定的方式呈現(xiàn)出來,這里我們只是打印出了文字。
- 缺陷:不管瀏覽器給我們發(fā)送什么請求,我們都只會返回hello world進行響應(yīng)。
3.2.2 version2
version2: 完成請求的解析,提取出url,返回對應(yīng)的網(wǎng)頁資源。
- 請求解析。
- 思路:
1. 首先我們從緩存區(qū)中提取的不知道是否是一個完整的報文。
2. 因此我們應(yīng)找到完整報文的解析符 ——\r\n\r\n
。
3. 一般情況下,瀏覽器是不會發(fā)送正文段的,因此我們按照沒有發(fā)送正文段的報文進行解析處理。- 拓展:我們可以看已經(jīng)截取的請求報頭中查看是否有Content-Length字段,如果有則有正文,解析其后的數(shù)據(jù)長度,截取正文段即可。
- InCode
string InConde(string& str){string splite_str = "\r\n\r\n";size_t pos = str.find(splite_str,0);//如果沒有找到說明不是一個完整的報文。if(pos == string::npos){return "";}int len = pos + splite_str.size();string package = str.substr(0,len);//將報文進行丟棄,便于截取下一次請求的報文。str.erase(0,len);return package; }
- 打散請求
- 思路:
因為都是以\r\n
以一行的形式進行呈現(xiàn)的,因此我們只需以\r\n
截取出每一行即可,然后添加到類型為vector<string> 的infors
即可。
- Deserialize
bool Deserialize(string& str){//先看是否有完整的報文string datagram = InConde(str);int cur = 0;while(true){size_t pos = datagram.find(line_break,cur);//從cur位置開始尋找。//如果沒有就說明解析出錯了。if(pos == string::npos) return false;string line = datagram.substr(cur,pos - cur); //截取pos - cur長度。cur = pos + line_break.size();//跳過line_breakif(line.empty()) break; //讀取到空行。infors.push_back(line);}return true;}
- 提取狀態(tài)行。
- 思路:
- 這里報文都存在
infors中
, 請求報頭都在infors[0]
中,因此我們將其解析出來即可。- 格式為:
[請求方法][空格][Url][空格][HTTP版本]
,以空格分隔出每一個元素即可。
除此之外,因為我們要從url中解析出相應(yīng)的返回資源,下面我們列出第一次訪問網(wǎng)址瀏覽器發(fā)送的兩次請求:
- 說明: 第一次請求的是主頁資源,主頁資源的url也可以為 /index.html,第二次請求的是網(wǎng)頁標簽的logo。
- 舉個百度標簽的logo:
根據(jù)url解析出相應(yīng)的文件信息,我們可以據(jù)此返回相應(yīng)的資源了。
- Prase
void Prase(){//對一行的資源進行處理string state_line = infors[0]; //[請求方法][空格][Url][空格][HTTP版本]auto left = state_line.find(space);auto right = state_line.rfind(space);//請求方法Method = state_line.substr(0,left);//urlUrl = state_line.substr(left + 1,right - left - 1);//請求的HTTP版本。Version = state_line.substr(right + 1);//看URL中是否帶有文件信息,如果有則解析出來,默認為 ".html"auto pos = Url.rfind('.');if(pos != string::npos){suffix = Url.substr(pos);//默認為.htmlif(content_type[suffix] == "") suffix = ".html";}}
- 構(gòu)造函數(shù):
HttpRequest(){content_type[".jpg"] = "image/jpeg";content_type[".html"] = "text/html";content_type[".ico"] = "image/x-icon";}
- 說明:
- 響應(yīng)時,我們返回對應(yīng)網(wǎng)頁資源時,得說明是什么類型的,瀏覽器會按照響應(yīng)的方式進行解析。
- 我們只需再狀態(tài)行添加
[Content-Type:][空格][資源文件的類型]
,比如:Content-Type: text/html
。
- 準備網(wǎng)頁資源。
我們在當(dāng)前目錄下創(chuàng)建一個wwwroot
作為根目錄,存放網(wǎng)頁資源文件,一般的網(wǎng)頁以 .html
結(jié)尾。
因此我們成員變量設(shè)置了:
const string root = "./wwwroot"; //獲取資源在服務(wù)器的路徑,即根目錄。
我們這里創(chuàng)建一個index.html
,寫一些網(wǎng)頁信息:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Shun_Hua</title>
</head>
<body><h1 >歡迎來到我的主頁!</h1>
</body>
</html>
- 說明:
- 首先博主采用的是vscode編寫較為輕量,寫起來也很輕松,按下
! 加上 Tab
可以快速生成一個網(wǎng)頁框架。- 這里涉及一些前端的知識,博主在寫項目時候總結(jié)了一下常用的,具體可見:詳見目錄前端編寫模塊 。
下面是如何找的過程,首先我們要從url獲取到文件的信息,再跟網(wǎng)頁的根目錄進行拼接,具體實現(xiàn)如下:
- GetSourse
string GetSourse(){//根據(jù)Url,確定返回的資源string path = root;//主頁資源。if(Url == "/" || Url == "/home.html")path += "/home.html";else{path += Url;}//從文件中讀取消息。return ReadFromFile(path);}
下一步是從獲取到的具體路徑文件中,讀取文件信息,作為正文段進行返回。
- ReadFromFile
string ReadFromFile(const string& path){//從文件中讀取對應(yīng)的內(nèi)容。std::ifstream fs(path,ios_base::in);if(!fs.is_open()) return "404 Not Found";string content;//直接讀取到文件的結(jié)尾fs.seekg(0,fs.end);//獲取文件的長度。auto len = fs.tellg();//回退到文件的長度。fs.seekg(0,fs.beg);//直接將內(nèi)容讀取出來,將內(nèi)容打到進去,這是比較暴力但是比較簡單的做法。content.resize(len);fs.read((char*)content.c_str(),content.size());return content;}
以上的代碼寫完之后,我們可以再寫一個更加高級的處理消息的函數(shù):
- HanderHttpMes
string HanderHttpMes(string &mes){HttpRequest req;//首先對mes進行解析,獲取完整的報文,解析失敗返回空串。if(!req.Deserialize(mes)) return "";//其次解析出報頭信息。req.Prase();//從Url中獲取相應(yīng)的網(wǎng)頁資源。string text = req.GetSourse(); //正文string empty_line = "\r\n"; //空行string state_line = "HTTP/1.1 200 OK\r\n";//狀態(tài)行string package_line = "Content-Length: " \+ to_string(text.size()) + empty_line;string content_type_line = "Content-Type: "\+ content_type[suffix] + empty_line;string response = state_line + package_line + empty_line + text;return response;}
- 效果:
- 返回的響應(yīng):
下面我們來一點前端的知識,讓頁面更加豐富多采一點:
- 增加網(wǎng)頁標簽logo
- 推薦網(wǎng)站:免費Favicon.ico圖標在線生成器
- 這里我輸入文字:舜華,進行自動生成?;蛘咧苯佑矛F(xiàn)成的也可以。
- 點擊圖片下載保存到能找到的文件夾。
- 在Linux會話窗口使用:
rz -E
命令,將.ico
文件上傳到Linux的存放網(wǎng)頁文件的目錄下。
然后我們再刷新網(wǎng)頁,看一看效果:
- 有總比沒有強,雖然顏色有點重,hhh。
此后,我們可以直接在網(wǎng)頁文件中編寫內(nèi)容,服務(wù)器啟動著,瀏覽器刷新即可更新出新的網(wǎng)頁內(nèi)容。
- 說明:以下所有更新文件都在
./wwwroot
路徑下。
更新網(wǎng)頁內(nèi)容:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Shun_Hua</title>
</head>
<body><h1 >歡迎來到我的主頁!</h1><!-- >更新內(nèi)容,添加網(wǎng)頁鏈接,可以跳轉(zhuǎn)到指定網(wǎng)頁 <--><a href="http://59.110.171.164:8888/"> 回到主頁 </a></br> <!-- >回車換行的意思<--><a href="http://59.110.171.164:8888/tail.html"> 尾頁 </a>
</body>
</html>
添加尾頁內(nèi)容:
- tail.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>尾頁</title>
</head>
<body><h1>歡迎來到尾頁!</h1><p>ps:功能開發(fā)中……</p><a href="http://59.110.171.164:8888/"> 回到主頁 </a>
</body>
</html>
刷新界面:
在尾頁添加圖片:
- 圖片 ——1.png
- tail.html
<!-- >說明:未補充內(nèi)容同上 <-->
<body><h1>歡迎來到尾頁!</h1><p>ps:功能開發(fā)中……</p><a href="http://59.110.171.164:8888/"> 回到主頁 </a><br><img src = "./1.jpg" alt="實在抱歉" width="200px" height="200px"><!-- >加載對應(yīng)的圖片,設(shè)置圖片加載失敗時的提示,設(shè)置圖片的寬度和高度 <-->
</body>
效果:
- 綜上所述,我們使用一點點前端知識,將網(wǎng)頁變的不至于那么單調(diào),簡單的完成與用戶進行交互。
- 說明:以上都是請求成功的情況,那有沒有請求失敗的的情況呢?下面我們繼續(xù)深入了解
響應(yīng)行和響應(yīng)報頭
。
3.2.3 version3
- version3: 學(xué)習(xí)響應(yīng)行和響應(yīng)報頭。
- 重定向
- 狀態(tài)碼:3XX,重定向,需要進一步的操作以完成請求。這里使用 302 Found。
- 狀態(tài)行: 既然重定向了,我們還得告訴瀏覽器的重定向的地址是什么,這里我們使用302,狀態(tài)行表示成:
[Location:][空格][網(wǎng)址][\r\n]
。
- HanderHttpMes
string HanderHttpMes(string &mes){HttpRequest req;string state_line = "HTTP/1.1 302 Found\r\n";//狀態(tài)行string location_line = "Location: https://www.baidu.com\r\n";string empty_line = "\r\n"; //空行string response = state_line + location_line + empty_line;return response;}
- 效果:
2. 網(wǎng)頁資源不存在
- 狀態(tài)碼:4XX,客戶端錯誤,請求包含語法錯誤或無法完成請求。這里使用 404 Not Found。
- 狀態(tài)行: 既然找不到,我們就返回一個表示找不到的網(wǎng)頁即可。
- HanderHttpMes
string HanderHttpMes(string &mes){//如果解析出來的Url不存在,我們可以直接返回錯誤界面,//這里我們只是簡單的演示一下效果。mes.resize(0);HttpRequest req;string text = ReadFromFile(root + "/errno.html") + "\r\n";string state_line = "HTTP/1.1 404 Not Found\r\n";//狀態(tài)行string len_line = "Content-Length: " + to_string(text.size()) + "\r\n"; string empty_line = "\r\n"; //空行string response = state_line + len_line + empty_line + text;return response;}
- errno.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404 Not Found</title>
<style>
body {
text-align: center;
padding: 150px;
}
h1 {
font-size: 50px;
}
body {
font-size: 20px;
}
a {
color: #008080;
text-decoration: none;
}
a:hover {
color: #005F5F;
text-decoration: underline;
}
</style>
</head>
<body>
<div>
<h1>404</h1>
<p>頁面未找到<br></p>
<p>
您請求的頁面可能已經(jīng)被刪除、更名或者您輸入的網(wǎng)址有誤。<br>
請嘗試使用以下鏈接或者自行搜索:<br><br>
<a href="https://www.baidu.com">百度一下></a>
</p>
</div>
</body>
</html>
- 說明:網(wǎng)上有現(xiàn)成的,直接拿來用即可。
- 效果:
- 設(shè)置cookie
概念:cookie是一種文本文件,會進行存儲記錄用戶的相關(guān)信息,發(fā)送給服務(wù)器進行認證。
優(yōu)點:下一次登錄時,會直接用已經(jīng)存儲好的cookie文件,無需再次登錄認證。
- 圖解:
如何查看呢?下面我們以CSDN的首頁進行舉例。
說明:cookie文件是有保質(zhì)期的,過期了cookie會無效,需要再次認證。
- HanderHttpMes
string HanderHttpMes(string &mes){//如果解析出來的Url不存在,我們可以直接返回錯誤界面,//這里我們只是簡單的演示一下效果。HttpRequest req;if(!req.Deserialize(mes)) return "";req.Prase();string text = req.GetSourse();string state_line = "HTTP/1.1 200 OK\r\n";//狀態(tài)行string len_line = "Content-Length: " + to_string(text.size()) + "\r\n";string cookie_line = "Set-Cookie: user=shun_hua&&password=123456\r\n"; string empty_line = "\r\n"; //空行string response = state_line + len_line + cookie_line + empty_line + text;return response;}
-
效果:
-
網(wǎng)頁中的cookie文件:
- 這里總結(jié)一下對響應(yīng)和請求的大致分類:
- 狀態(tài)碼
狀態(tài)碼 | 狀態(tài)描述 |
---|---|
1XX | 信息,服務(wù)器收到請求,需要請求者繼續(xù)執(zhí)行操作 |
2XX | 成功,操作被成功接收并處理 |
3XX | 重定向,需要進一步的操作以完成請求 |
4XX | 客戶端錯誤,請求包含語法錯誤或無法完成請求 |
5XX | 服務(wù)器錯誤,服務(wù)器在處理請求的過程中發(fā)生了錯誤 |
- 當(dāng)我們使用具體的狀態(tài)碼時,查表即可,但是我們要對狀態(tài)碼的分類比較清楚,上面我們使用了404,302,200進行了演示。
- Header
Header | 描述 |
---|---|
Content-Type: | 數(shù)據(jù)類型(text/html等) |
Content-Length: | Body的長度 |
Host: | 客戶端告知服務(wù)器, 所請求的資源是在哪個主機的哪個端口上; |
User-Agent: | 聲明用戶的操作系統(tǒng)和瀏覽器版本信息; |
referer: | 當(dāng)前頁面是從哪個頁面跳轉(zhuǎn)過來的; |
location: | 搭配3xx狀態(tài)碼使用, 告訴客戶端接下來要去哪里訪問; |
Cookie: | 用于在客戶端存儲少量信息. 通常用于實現(xiàn)會話(session)的功能 |
- 常用狀態(tài)碼與響應(yīng)頭
- 請求方法
請求方法 | 描述 |
---|---|
GET | 請求指定的頁面信息,并返回實體主體。 |
POST | 向指定資源提交數(shù)據(jù)進行處理請求(例如提交表單或者上傳文件)。數(shù)據(jù)被包含在請求體中。POST 請求可能會導(dǎo)致新的資源的建立和/或已有資源的修改。 |
HEAD | 類似于 GET 請求,只不過返回的響應(yīng)中沒有具體的內(nèi)容,用于獲取報頭 |
PUT | 從客戶端向服務(wù)器傳送的數(shù)據(jù)取代指定的文檔的內(nèi)容。 |
DELETE | 請求服務(wù)器刪除指定的頁面。 |
CONNECT | HTTP/1.1 協(xié)議中預(yù)留給能夠?qū)⑦B接改為管道方式的代理服務(wù)器。 |
OPTIONS | 允許客戶端查看服務(wù)器的性能。 |
TRACE | 回顯服務(wù)器收到的請求,主要用于測試或診斷。 |
PATCH | 是對 PUT 方法的補充,用來對已知資源進行局部更新 。 |
- 說明:大多數(shù)請求都是Get和Post,其它的我們當(dāng)做了解即可。
總結(jié)
- 我們認識了一些現(xiàn)成的應(yīng)用層協(xié)議,比如SMTP,FTP,SSH等。
- 了解了Http的基本概念,比如域名,默認端口號,統(tǒng)一資源定位符。
- 介紹了三個抓包工具,fiddler,postman,apifox。
- 使用telnet工具發(fā)送請求,接收響應(yīng)。并列出了請求和響應(yīng)的框架,據(jù)此學(xué)習(xí)了長連接和短連接的知識。
- 編程實踐,編寫一個網(wǎng)絡(luò)的Server服務(wù)和Request類處理請求,通過此學(xué)習(xí)了常用的請求行的狀態(tài)碼,請求報頭等,一些網(wǎng)頁的前端知識,比如標題logo,圖片,鏈接,編寫了一個簡單網(wǎng)頁。
- 下期預(yù)告:
我們此文提及了cookie一般是含認證信和密碼之類的信息
,但http是明文傳輸?shù)?/code>,這就導(dǎo)致了數(shù)據(jù)在網(wǎng)絡(luò)中是不安全的,這就涉及到了加密,據(jù)此引出下篇文章要討論的
Https
,敬請期待!。
尾序
我是舜華,期待與你的下一次相遇!