当前位置: 首页 > news >正文

购买已备案网站做非法新网站怎么快速收录必做

购买已备案网站做非法,新网站怎么快速收录必做,熊掌号接合网站做seo,买域名建网站价格本篇博客整理了 TCP/IP 分层模型中应用层的 HTTP 协议和 HTTPS协议#xff0c;旨在让读者更加深入理解网络协议栈的设计和网络编程。 目录 一、协议是什么 1#xff09;结构化数据的传输 2#xff09;序列化和反序列化 补#xff09;网络版计算器 .1- 协议定制 .2- …        本篇博客整理了 TCP/IP 分层模型中应用层的 HTTP 协议和 HTTPS协议旨在让读者更加深入理解网络协议栈的设计和网络编程。 目录 一、协议是什么 1结构化数据的传输 2序列化和反序列化 补网络版计算器 .1- 协议定制 .2- 服务端 .3- 客户端 .4- 测试效果 二、HTTP 协议 1网址 URL .1- 协议方案名 .2- 登录信息 .3- 服务器地址 .4- 服务器端口号 .5- 带层次的文件路径 .6- 查询字符串 .7- 片段标识符 2urlencode 和 urldecode 3HTTP 协议格式 .1- 请求协议格式 .补- 模拟获取浏览器的 HTTP 请求 .2- 响应协议格式 .补- 模拟构建HTTP并响应给浏览器 4常用方法 5状态码 6常见报头 7Cookie 和 Session .1- Set-Cookie 字段与 cookie 文件 .2- cookie 被盗与 SessionID .补- 实验演示 Set-Cookie 字段 三、HTTPS 协议 1HTTPS 与 HTTP 2对称加密与非对称加密 一、协议是什么 协议是网络协议的简称。网络协议是通信计算机双方必须共同遵从的一组约定内容包括怎么建立连接、怎么互相识别等。 为了使数据在网络上能够从源到达目的网络通信的参与方必须遵循相同的规则而这套规则被称为协议protocol最终都需要通过计算机语言的方式表现出来。只有通信计算机双方都遵守相同的协议计算机之间才能互相通信交流。  简单来说协议主要应用在数据的传输过程中是需要通过数据来通信的双方共同遵守的一种约定。 1结构化数据的传输 通信双方在进行网络通信时如果需要传输的数据是一个字符串只需直接将这个字符串发送到网络中对端就能从网络中获取如果需要传输的是一些结构化的数据就不能将这些数据一个个发送到网络当中。 将这些结构化的数据单独一个个的发送到网络当中那么对端也只能从网络中一个个获取此后对端还得弄清楚如何将数据组合还原这就使数据的传输过程十分复杂。因此最好把这些结构化的数据打包统一发送到网络中这样一来对端每次从网络中获取到的就是一份完整的数据。而这种结构化数据的传输情景就经常发生于客户端向服务端发送数据请求。 【Tips】网络通信中常见的数据“打包”方式 将结构化的数据组合成一个字符串         例如客户端可以按某种方式将这些结构化的数据组合成一个字符串然后将这个字符串发送到网络中这样一来服务端每次从网络中获取到字符串后再以相同的方式对这个字符串进行解析就能提取出这些结构化的数据。 定制结构体 序列化和反序列化         例如客户端可以定制一个结构体将数据请求的相关信息都封装在这个结构体中。客户端发送数据时先对数据进行序列化将其转换成网络标准数据格式并发送到网络中服务端接收到数据后再对其进行反序列化按照与序列化相同的规则把接收到的数据转化为结构体然后从结构体中提取出数据请求的相关信息。 2序列化和反序列化 数据的传输离不开网络协议栈而网络协议栈是分层的。 在 OSI 参考模型中表示层的作用就是实现设备固有数据格式和网络标准数据格式的转换。其中设备固有的数据格式指的是数据在应用层上的格式而网络标准数据格式则指的是序列化之后可以进行网络传输的数据格式。 【Tips】序列化和反序列化的目的 序列化将对象的状态信息转换为可以存储或传输的形式字节序列。                 在网络传输时序列化目的是为了方便网络数据的发送和接收无论是何种类型的数据在网络数据传输的底层统一是二进制序列的。 反序列化把字节序列恢复为对象。         经序列化后的二进制序列数据只能在网络传输的底层被识别而无法在上层应用被识别因此就需要进行反序列化将从网络中获取的二进制序列数据转换成应用层能够识别的数据格式。         可以认为网络通信和业务处理是处于不同层级的。         在进行网络通信时底层能看到的都是二进制序列的数据而在进行业务处理时上层能看得到则是可以被上层识别的数据。如果数据需要在业务处理和网络通信之间进行传输就需要对数据进行对应的序列化或反序列化操作。 补网络版计算器 .1- 协议定制 要实现一个既有服务端又有客户端的网络版计算器首先得保证通信双方遵守了某种协议。 服务端和客户端发送和接收的数据可以分为请求数据和响应数据因此就需要分别对请求数据和响应数据进行约定此处用结构体来实现分别实现一个请求结构体和一个响应结构体。 请求结构体是针对于客户端的客户端是负责向服务端发送计算式问题的因此请求结构体中要包括两个操作数和对应的运算操作、运算符。 响应结构体是针对于服务端的服务端是负责向客户端响应计算结果的因此响应结构体中要包括一个计算结果。此外还要包括一个状态字段以表示本次计算是否有意义并规定状态字段的含义如下 状态字段为 0表示计算成功。状态字段为 1表示出现除 0 错误。状态字段为 2表示出现模 0 错误。状态字段为 3表示非法计算。 协议定制好后必须要被客户端和服务端同时看到这样它们才能遵守这个约定因此将请求结构体和响应结构体写到一个头文件中并让客户端和服务端都应该包含这个头文件。 protocol.hpp #pragma once #include iostream #include string #include cstring #include sys/socket.h #include sys/types.h #include netinet/in.h #include arpa/inet.h #include unistd.h using namespace std;//请求 typedef struct request{int x; //左操作数int y; //右操作数char op; //操作符 }request_t;//响应 typedef struct response{int code; //计算状态int result; //计算结果 }response_t;.2- 服务端 客户端和服务端在发送或接收数据时既可以使用 write() 和 read() 来实现也可以使用 send() 或 recv() 来实现。 #includesys/type.h #includesys/socket.h ssize_t send(int sockfd, const void *buf, size_t len, int flags); 功能向accept()返回的套接字中写入数据用于服务端向客户端回应数据、客户端向服务端发送数据。 参数1.sockfd待写入数据的文件描述符。2.buf指向待发送的数据。3.len待发送数据的字节数。4.flags发送的方式一般设置为0表示阻塞式发送。 返回值写入成功则返回实际写入的字节数写入则失败返回-1并设置合适的错误码。#includesys/type.h #includesys/socket.h ssize_t recv(int sockfd, void *buf, size_t len, int flags); 功能从accept()返回的套接字中读取数据用于服务端读取客户端发来的数据、客户端向服务端回应数据。 参数1.sockfd待读取数据的文件描述符。2.buf将读取到的数据存储 buf 所指的位置。3.len待读取数据的字节数。4.flags发送的方式一般设置为0表示阻塞式读取。 返回值返回值 0 时表示实际读取到的字节数。返回值 0 时表示对端客户端已关闭连接服务端不再为其提供服务。返回值 0 时表示读取失败并设置合适的错误码。 server.cc #include protocol.hpp//线程例程 void* Routine(void* arg); //主线程 int main(int argc, char* argv[]) {if (argc ! 2){cerr Usage: argv[0] port endl;exit(1);}int port atoi(argv[1]);//1.创建套接字//使用 IPv4 的协议簇、使用 TCP 协议int listen_sock socket(AF_INET, SOCK_STREAM, 0);if (listen_sock 0){cerr socket error! endl;exit(2);}//2.绑定struct sockaddr_in local;memset(local, 0, sizeof(local));local.sin_family AF_INET;local.sin_port htons(port);local.sin_addr.s_addr htonl(INADDR_ANY);if (bind(listen_sock, (struct sockaddr*)local, sizeof(local)) 0){cerr bind error! endl;exit(3);}//3.监听if (listen(listen_sock, 5) 0){cerr listen error! endl;exit(4);}//4.运行struct sockaddr peer;memset(peer, 0, sizeof(peer));while(1){//1获取数据请求socklen_t len sizeof(peer);int sock accept(listen_sock, (struct sockaddr*)peer, len);if (sock 0){cerr accept error! endl;continue;}//2创建子线程处理数据请求pthread_t tid 0;int* p new int(sock);pthread_create(tid, nullptr, Routine, p);}return 0; }void* Routine(void* arg) {//分离线程pthread_detach(pthread_self()); //提供服务int sock *(int*)arg;delete (int*)arg;while (1){request_t rq;ssize_t size recv(sock, rq, sizeof(rq), 0);if (size 0){//计算response_t rp { 0, 0 };switch (rq.op){case :rp.result rq.x rq.y;break;case -:rp.result rq.x - rq.y;break;case *:rp.result rq.x * rq.y;break;case /:if (rq.y 0){rp.code 1; //除0错误}else{rp.result rq.x / rq.y;}break;case %:if (rq.y 0){rp.code 2; //模0错误}else{rp.result rq.x % rq.y;}break;default:rp.code 3; //非法运算break;}//向客户端响应结果send(sock, rp, sizeof(rp), 0);}else if (size 0){cout service done endl;break;}else{cerr read error endl;break;}}close(sock);return nullptr; } .3- 客户端 client.cc #include protocol.hppint main(int argc, char* argv[]) {if (argc ! 3){cerr Usage: argv[0] server_ip server_port endl;exit(1);}string server_ip argv[1];int server_port atoi(argv[2]);//1.创建套接字//使用 IPv4 的协议簇、使用 TCP 协议int sock socket(AF_INET, SOCK_STREAM, 0);if (sock 0){cerr socket error! endl;exit(2);}//2.连接服务器struct sockaddr_in peer;memset(peer, 0, sizeof(peer));peer.sin_family AF_INET;peer.sin_port htons(server_port);peer.sin_addr.s_addr inet_addr(server_ip.c_str());if (connect(sock, (struct sockaddr*)peer, sizeof(peer)) 0){cerr connect failed! endl;exit(3);}//3.运行while (1){//构建请求request_t rq;cout 请输入左操作数# ;cin rq.x;cout 请输入右操作数# ;cin rq.y;cout 请输入需要进行的操作[-*/%]# ;cin rq.op;//发送请求send(sock, rq, sizeof(rq), 0);//接收服务端的响应数据response_t rp;recv(sock, rp, sizeof(rp), 0);cout status: rp.code endl;cout rq.x rq.op rq.y rp.result endl;}return 0; }.4- 测试效果 Makefile .PHONY:all all:client serverclient:client.ccg -o $ $^ -stdc11 server:server.ccg -o $ $^ -stdc11 -lpthread.PHONY:clean clean:rm -f client server 二、HTTP 协议 在进行网络编程时协议可以自行定制也可以使用前人的定制。有很多优秀的工程师已经写出了许多非常成熟的应用层协议其中最典型的就是 HTTP 协议。 HTTP 协议Hyper Text Transfer Protocol又叫做超文本传输协议通常运行在 TCP 之上是一个简单的“请求—响应”协议。 1网址 URL URLUniform Resource Lacator是统一资源定位符也就是通常所说的网址是因特网的万维网服务程序上用于指定信息位置的表示方法。 【Tips】URL 的构成 .1- 协议方案名 http:// 所指的就是协议方案名表示请求时需要使用的协议。 通常使用的是 HTTP 协议或 HTTPS 安全协议。其中HTTPS 是以安全为目标的 HTTP 通道在HTTP 的基础上通过传输加密和身份认证保证了传输过程的安全性。 【补】常见的应用层协议 DNSDomain Name System域名系统。FTPFile Transfer Protocol文件传输协议。TELNETTelnet远程终端协议。HTTPHyper Text Transfer Protocol超文本传输协议。HTTPSHyper Text Transfer Protocol over SecureSocket Layer安全数据传输协议。SMTPSimple Mail Transfer Protocol电子邮件传输协议。POP3Post Office Protocol - Version 3邮件读取协议。SNMPSimple Network Management Protocol简单网络管理协议。TFTPTrivial File Transfer Protocol简单文件传输协议。 .2- 登录信息 usr:pass 表示的是登录认证信息其中包括登录用户的用户名和密码。 虽然登录认证信息可以在 URL 中体现出来但在绝大多数 URL 中这个字段都是被省略的这是因为登录信息可以通过其他方案交付给服务器。 .3- 服务器地址 www.example.jp 表示的是服务器地址也叫做域名又例如 www.qq.com、www.baidu.com等。 【Tips】域名 vs IP 地址         IP 地址虽然可以标识公网内的任意一台主机但本身并不适合让用户看。         例如 www.baidu.com 这个域名解析后的 IP 地址为 153.3.238.110指令 ping 可以获取域名解析后的 IP 地址如果用户在访问网站时看到的是这个 IP 地址那么 ta 在访问网站之前恐怕都不清楚这个网站到底是做什么的但如果用户看到的是 www.baidu.com 这个域名那么 ta 可以至少知道这个网站是属于哪家公司的。         因此相比 IP 地址域名具有更好的自描述性。          但在计算机中域名和 IP 地址其实几乎是等价的两者的使用效果相同只不过URL 要呈现给用户所以 URL 选择了域名来表示服务器地址。 .4- 服务器端口号 80 表示的就是服务器端口号。 HTTP 协议和套接字编程一样都是位于应用层的。在进行套接字编程时需要给服务器绑定对应的 IP 地址和端口号而这里的应用层协议也同样需要有明确的端口号。 用户使用的协议本质是要为用户提供服务的因此也需要绑定端口号。不过如今常用的协议与端口号之间的对应关系基本已经明确的于是在使用某种协议时已经无需指明该协议对应的端口号。因此在 URL 中服务器的端口号一般也是被省略的。 【Tips】常见协议的端口号 .5- 带层次的文件路径 /dir/index.htm 表示的就是要访问的资源所在的路径。 访问服务器的目的本质是从服务器上获取某种资源虽通过前面的域名和端口号已经能够找到对应的服务器进程了但接下来还要指明资源所在的路径。 例如打开浏览器并输入百度的域名浏览器会获取到百度的首页。 发起网页请求时会获得如下的网页信息然后浏览器对这张网页信息进行解释最终呈现出了对应的网页。  任意网页按下 F12 键即可查看 这种网页信息就是所谓的网页资源。 此外还可以看到网页信息中的路径分隔符是 / 而不是 \这也就说明其实很多服务都是部署在 Linux 上的。 除了发起网页请求以打开网页还可以向服务器请求视频、音频、网页、图片等非普通文本资源这也是 HTTP 叫做超文本传输协议的原因。 .6- 查询字符串 uid1 表示的就是请求时提供的额外的参数。这些参数是以键值对的形式通过符合 分隔开的。 例如在百度上搜索 HTTP 时可以看到 URL 中的很多参数其中有一个参数 wdword就表示搜索时的关键字 wdHTTP。 由此进行网络通信时通信双方其实是可以通过 URL 来进行用户数据传输的。  .7- 片段标识符 ch1 表示的就是片段标识符是对资源的部分补充。 当需要在网址中定位某一个网页的位置时可以通过片段标识符来定位。 【Tips】获取片段标识符的方法 在网页中右键选择选项中的检查查看网页源代码。按下 ctrl f 在搜索框 搜索 id 这个标签。 2urlencode 和 urldecode 像 /?: 等这样的字符, 已经被 URL 当做特殊意义理解了因此这些字符不能随意出现。 如果某个参数中需要带有这些特殊字符,就必须先对特殊字符进行转义。 【Tips】转义规则 将需要转码的字符转为十六进制从右到左取4位不足4位直接处理每两位做一位前面加上%编码成%XY格式。 例如在百度上搜索C由于  在 URL 中是特殊符号因此需对 进行转义。由转义规则 的十六进制的值为 0x2B由此 就会被编码成一个 %2B。 【ps】URL 中除了会对这些特殊符号做编码也会对中文进行编码。 【补】在线编码工具 UrlEncode编码/UrlDecode解码 - 站长工具 选中 URL 编码/解码模式在输入 C 后点击编码就能得到编码后的结果 对编码进行解码后的结果 【ps】服务器拿到 URL 后也需要对编码后的参数进行解码才能拿到用户传递的参数。解码本身也是编码的逆过程。 3HTTP 协议格式 网络协议栈是分层每一层都有属于自己的协议。 TCP/IP 分层模型中包含了应用层、网络层、传输层、数据链路层等。其中应用层常见的协议有 HTTP 和 HTTPS传输层有 TCP 和 UDP网络层有 IP数据链路层有 MAC 帧。 应用层负责如何使用传输过来的数据应用层的下三层则负责通信细节。下三层的通信细节是由操作系统或驱动来完成的如果仅考虑应用层而不考虑下三层那么就可以认为己方的应用层能够和对方的应用层直接进行数据交互。 要使用传输过来的数据就需要用到定制的协议其中最典型的就是 HTTP 协议。 HTTP 是基于请求和响应的应用层服务。作为客户端可以向服务器发起数据请求request当服务器收到数据请求后会对请求做数据分析得出客户端要访问什么资源然后再构建数据响应response以完成这一次 HTTP 的请求。这种基于“request response”的工作方式被称之为 cs 模式client server或 bs 模式browser server。  由于 HTTP 是基于请求和响应的应用层访问因此对应的请求格式和响应格式是十分重要的。 .1- 请求协议格式 【Tips】HTTP 请求由以下四部分组成 请求行包括请求方法、url 网址、http版本。请求报头请求的属性以“key: value”形式按行陈列。空行表示请求报头结束。请求正文允许为空字符串。如果请求正文存在则其中会有一个Content-Length属性来标识其长度。         前三部分是一般是 HTTP 协议自带的由 HTTP 协议自行设置。第四部分请求正文一般是用户的相关信息或数据如果用户在请求时没有信息要上传给服务器请求正文就为空字符串。 【补】按 \n 分离 HTTP 的报头与有效载荷         在网络通信中在 TCP/IP 模型的每一层中都存在一种协议而每一种协议的最终表现就是协议要有协议报头也就是说协议通常是通过协议报头来表达的且每一份数据在被发送或者处于不同的协议层中都要有自己的报头。数据在 TCP/IP 模型中以报文的形式传递而报文由报头和有效载荷组成。对于报头和有效载荷TCP/IP 模型的每一层都得必须具备将其封装与分离的能力只有这样才能将这一层有用的数据封装起来或解析出来。         因此当应用层收到一个 HTTP 请求时它必须想办法分离 HTTP 的报头与有效载荷以获取关键数据。         在 HTTP 请求的组成中请求行和请求报头其实就是 HTTP 的报头信息而请求正文其实就是 HTTP 的有效载荷。         一般可以根据 HTTP 请求中的空行来分离报头与有效载荷。当服务器收到一个 HTTP 请求后就按行进行读取如果读取到空行则说明此时已将报头读取完毕。如果将 HTTP 请求想象成一个大的线性结构那么每行的内容都是用 \n 隔开的因此在读取过程中如果连续读取到了两个 \n就说明已经将报头读取完毕了后面剩下的就都是有效载荷了。 .补- 模拟获取浏览器的 HTTP 请求 http_server.cc #include iostream #include fstream #include string #include cstring #include unistd.h #include sys/wait.h #include sys/socket.h #include sys/types.h #include netinet/in.h #include arpa/inet.h using namespace std;int main() {//1.创建套接字int listen_sock socket(AF_INET, SOCK_STREAM, 0);if (listen_sock 0){cerr socket error! endl;return 1;}//2.绑定struct sockaddr_in local;memset(local, 0, sizeof(local));local.sin_family AF_INET;local.sin_port htons(8888); //绑定端口号为 8888local.sin_addr.s_addr htonl(INADDR_ANY);if (bind(listen_sock, (struct sockaddr*)local, sizeof(local)) 0){cerr bind error! endl;return 2;}//3.监听if (listen(listen_sock, 5) 0){cerr listen error! endl;return 3;}//4.运行struct sockaddr peer;memset(peer, 0, sizeof(peer));socklen_t len sizeof(peer);while(1){//爷爷进程负责获取 HTTP 请求int sock accept(listen_sock, (struct sockaddr*)peer, len);if (sock 0){cerr accept error! endl;continue;}//爸爸进程负责创建孙子进程并退出if (fork() 0){ close(listen_sock);if (fork() 0){ exit(0);}//孙子进程负责读取和打印 HTTP 请求char buffer[1024];recv(sock, buffer, sizeof(buffer), 0); cout [ http request begin ] endl endl;cout buffer endl;cout [ http request end ] endl endl;close(sock);exit(0);}close(sock);waitpid(-1, nullptr, 0); }return 0; }①服务器运行之初 ②用浏览器Microsoft Edge登陆云服务器的IP地址端口号 .2- 响应协议格式 【Tips】HTTP 响应由以下四部分组成 状态行包括 http 版本、状态码、状态码描述。响应报头响应的属性以“key: value”的形式陈列。空行表示响应报头结束。响应正文允许为空字符串。如果响应正文存在则其中会有一个 Content-Length 属性来标识响应正文的长度。例如服务器返回了一个 html 页面那么返回的 html 页面的内容就是在响应正文中的。 .补- 模拟构建HTTP并响应给浏览器 http_server.cc #include iostream #include fstream #include string #include cstring #include unistd.h #include sys/wait.h #include sys/socket.h #include sys/types.h #include netinet/in.h #include arpa/inet.h using namespace std;int main() {//1.创建套接字int listen_sock socket(AF_INET, SOCK_STREAM, 0);if (listen_sock 0){cerr socket error! endl;return 1;}//2.绑定struct sockaddr_in local;memset(local, 0, sizeof(local));local.sin_family AF_INET;local.sin_port htons(8888); //绑定端口号为 8888local.sin_addr.s_addr htonl(INADDR_ANY);if (bind(listen_sock, (struct sockaddr*)local, sizeof(local)) 0){cerr bind error! endl;return 2;}//3.监听if (listen(listen_sock, 5) 0){cerr listen error! endl;return 3;}//4.运行struct sockaddr peer;memset(peer, 0, sizeof(peer));socklen_t len sizeof(peer);while(1){//爷爷进程负责获取 HTTP 请求int sock accept(listen_sock, (struct sockaddr*)peer, len);if (sock 0){cerr accept error! endl;continue;}//爸爸进程负责创建孙子进程并退出if (fork() 0){ close(listen_sock);if (fork() 0){ exit(0);}//孙子进程//读取和打印 HTTP 请求char buffer[1024];recv(sock, buffer, sizeof(buffer), 0); cout [ http request begin ] endl endl;cout buffer endl;cout [ http request end ] endl endl;//构建一个简单的 HTTP 响应std::string HttpResponse HTTP/1.1 200 OK\r\n; // 状态行HttpResponse \r\n; // 空行HttpResponse htmlh1Hello NeeEk0 /h1/html; // 正文//发送 HTTP 响应send(sockfd, HttpResponse.c_str(), HttpResponse.size(), 0);close(sock);exit(0);}close(sock);waitpid(-1, nullptr, 0); }return 0; }①服务端运行之初 ②用浏览器Microsoft Edge登陆云服务器的IP地址端口号         服务端收到并打印了浏览器的请求信息。         浏览器收到并显示了服务端的响应信息。 4常用方法 GET 和 POST 是最常用的 HTTP 方法。 【Tips】GET 和 POST         GET 方法 一般用于获取某种资源信息。通过 url 传参会将参数回显到 url 中。         POST 方法 一般用于将数据上传给服务器。但上传数据时也有可能使用 GET 方法例如百度提交数据时使用的其实是 GET 方法。通过正文传参由此能传递更多的参数数据。此外不会将参数回显到 url 中因此更加私密。 【ps】POST 方法不会将参数回显到 url 中并不意味着 POST 方法更安全。实际上 GET 和POST 方法传参时都是明文传送因此都不安全只不过 POST 方法的传参更私密。 以下借助 TCP 套接字来演示 GET 和 POST 的区别。 为方便演示此处在 TCP 服务端进程所在的目录下创建一个 html 文件并修改上文服务端的代码将响应内容设置为 html 文件中的内容。这样一来浏览器访问服务端后显示就是 html 文件中的内容了。 index.html !DOCTYPE html html langen headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleTestGET/title /head bodyh1测试GET/h1p /* 段落部分 *//pform nameinput action/a/b/c methodGETUsername: input typetext nameuserbr/Password: input typepassword namepwd br/input typesubmit valueSubmit/form /body /html 其中action 属性指定将表单提交给服务端上的哪个资源method 属性指定参数提交的方法为 GET。 http_server.cc #include iostream #include fstream #include string #include cstring #include unistd.h #include sys/wait.h #include sys/socket.h #include sys/types.h #include netinet/in.h #include arpa/inet.h using namespace std;#define PAGE index.html int main() {//1.创建套接字int listen_sock socket(AF_INET, SOCK_STREAM, 0);if (listen_sock 0){cerr socket error! endl;return 1;}//2.绑定struct sockaddr_in local;memset(local, 0, sizeof(local));local.sin_family AF_INET;local.sin_port htons(8888); //绑定端口号为 8888local.sin_addr.s_addr htonl(INADDR_ANY);if (bind(listen_sock, (struct sockaddr*)local, sizeof(local)) 0){cerr bind error! endl;return 2;}//3.监听if (listen(listen_sock, 5) 0){cerr listen error! endl;return 3;}//4.运行struct sockaddr peer;memset(peer, 0, sizeof(peer));socklen_t len sizeof(peer);while(1){//爷爷进程负责获取 HTTP 请求int sock accept(listen_sock, (struct sockaddr*)peer, len);if (sock 0){cerr accept error! endl;continue;}//爸爸进程负责创建孙子进程并退出if (fork() 0){ close(listen_sock);if (fork() 0){ exit(0);}//孙子进程//读取和打印 HTTP 请求char buffer[1024];recv(sock, buffer, sizeof(buffer), 0); cout [ http request begin ] endl endl;cout buffer endl;cout [ http request end ] endl endl;//读取 index.html 文件ifstream in(PAGE);if (in.is_open()){in.seekg(0, in.end);int len in.tellg();in.seekg(0, in.beg);char* file new char[len];in.read(file, len);in.close();//构建 HTTP 响应//状态行string status_line http/1.1 200 OK\n; //响应报头string response_header Content-Length: to_string(len) \n;//空行string blank \n; //响应正文string response_text file; //响应报文string response status_line response_header blank response_text; //响应HTTP请求send(sock, response.c_str(), response.size(), 0);delete[] file;}close(sock);exit(0);}close(sock);waitpid(-1, nullptr, 0); }return 0; }将上文中的 TCP 服务端运行在浏览器上输入“云服务器 IP 地址:端口号”即可访问这个 html 文件。 服务端收到了浏览器的请求         浏览器显示了服务端的响应         在浏览器中填充完用户名和密码并进行提交后用户名和密码就会自动被同步到 url 中         同时服务端通过 url 也收到了在浏览器提交的参数。 接下来将 html 文件中的 method 属性从 GET 改为 POST。 index.html !DOCTYPE html html langen headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleTestPOST/title /head bodyh1测试POST/h1p /* 段落部分 *//pform nameinput action/a/b/c methodPOSTUsername: input typetext nameuserbr/Password: input typepassword namepwd br/input typesubmit valueSubmit/form /body /html 再次在浏览器上输入 “云服务器 IP 地址:端口号”         此时填充完用户名和密码并进行提交后提交的参数不会在 url 中体现而会通过正文传递给服务端 5状态码 最常见的状态码例如 200OK404Not Found403Forbidden请求权限不够302Redirect504Bad Gateway 【补】重定向状态码Redirection         重定向是指。通过各种方法将各种网络请求转到其它位置相当于服务器提供了一个引路服务。         它又可分为临时重定向和永久重定向其中状态码 301 表示的就是永久重定向而状态码 302 和 307 表示的是临时重定向。         临时重定向和永久重定向本质是影响客户端的标签可以决定客户端是否需要更新目标地址。         如果某个网站是永久重定向的那么第一次访问该网站时就由浏览器帮助进行重定向但后续再访问就无需浏览器进行重定向了可以直接重定向后的网站如果某个网站是临时重定向的那么每次访问该网站时都需要进行重定向那么就都需要浏览器来帮助完成重定向并跳转到目标网站。 【补】演示临时重定向         进行临时重定向时需要用到 HTTP 报头中的 Location 字段以表明了要重定向的目标网站此处重定向为 CSDN 的首页。 http_server #include iostream #include fstream #include string #include cstring #include unistd.h #include sys/wait.h #include sys/socket.h #include sys/types.h #include netinet/in.h #include arpa/inet.h using namespace std;int main() {//1.创建套接字int listen_sock socket(AF_INET, SOCK_STREAM, 0);if (listen_sock 0){cerr socket error! endl;return 1;}//2.绑定struct sockaddr_in local;memset(local, 0, sizeof(local));local.sin_family AF_INET;local.sin_port htons(8888); //绑定端口号为 8888local.sin_addr.s_addr htonl(INADDR_ANY);if (bind(listen_sock, (struct sockaddr*)local, sizeof(local)) 0){cerr bind error! endl;return 2;}//3.监听if (listen(listen_sock, 5) 0){cerr listen error! endl;return 3;}//4.运行struct sockaddr peer;memset(peer, 0, sizeof(peer));socklen_t len sizeof(peer);while(1){//爷爷进程负责获取 HTTP 请求int sock accept(listen_sock, (struct sockaddr*)peer, len);if (sock 0){cerr accept error! endl;continue;}//爸爸进程负责创建孙子进程并退出if (fork() 0){ close(listen_sock);if (fork() 0){ exit(0);}//孙子进程//读取和打印 HTTP 请求char buffer[1024];recv(sock, buffer, sizeof(buffer), 0); cout [ http request begin ] endl endl;cout buffer endl;cout [ http request end ] endl endl;//构建 HTTP 响应//将状态码设置为 307并跟上相应的状态码描述string status_line http/1.1 307 Temporary Redirect\n; //重定向为 CSDN 的首页string response_header Location: https://www.csdn.net/\n; string blank \n; string response status_line response_header blank; //响应 HTTP 请求send(sock, response.c_str(), response.size(), 0);close(sock);exit(0);}close(sock);waitpid(-1, nullptr, 0); }return 0; }6常见报头 【Tips】HTTP 常见的报头 Content-Type数据类型text/html等。Content-Length正文的长度。Host客户端告知服务器所请求的资源是在哪个主机的哪个端口上。User-Agent声明用户的操作系统和浏览器的版本信息。Referer当前页面是哪个页面跳转过来的。Location搭配3XX状态码使用告诉客户端接下来要去哪里访问。Cookie用于在客户端存储少量信息通常用于实现会话session的功能。 【Tips】Host 字段         Host 用于表明客户端要访问的服务器 IP 和端口。         有一些服务器实际提供的是一种代理服务也就是代替客户端向其他服务器发起请求然后将请求结果再返回给客户端在这种情况下客户端就必须告诉代理服务器它要访问的 IP 和端口以指明它真正要访问的服务器。 【Tips】User-Agent 字段         User-Agent 用于表示客户端的操作系统和浏览器的版本信息。         在用网站下载某些软件时网站一般会自动展示与操作系统相匹配的软件版本这是因为在向目标网站发起请求时User-Agent 字段中包含了主机信息使网站能够推送合适的软件版本。 【Tips】Referer 字段         Referer 能够记录访问的上一个页面用于表示当前是从哪一个页面跳转过来的。         Referer 的优点一方面是方便回退另一方面可以让用户知道当前页面与上一个页面之间的相关性。 【Tips】Keep-Alive长连接字段         如果 HTTP 请求或响应报头中Connect 字段的值是 Keep-Alive就表示支持长连接。         HTTP/1.0 是通过“请求—响应”的方式来进行请求和响应的常见的工作方式就是客户端先与服务器建立链接并向服务器发起请求然后服务器对请求进行响应并进行端口连接。         但如果一个连接建立后客户端和服务器只进行一次交互就将连接关闭未免太浪费资源因此现在主流的 HTTP/1.1 是支持长连接的。         所谓的长连接就是建立连接后客户端可以不断的向服务器一次写入多个 HTTP 请求而服务器可以在上层依次读取这些请求。这样一来一条连接就可以传送大量的请求和响应。 7Cookie 和 Session HTTP 是一种无状态协议也就是说。HTTP 的每次请求与响应之间是没有任何关系的。 然而在使用浏览器的时候发现并不是这样的例如在 CSDN 网站上登录过一次个人账号就算把网站关闭甚至重启电脑再次打开网站时个人账户仍然登录在案且网站并没有要求再次输入账号和密码。 这其实是通过 cookie 技术实现的。 点击浏览器中锁的标志就可以看到当前网站的各种 cookie 数据。         这些 cookie 数据都是由相应的服务器来写的如果将某些登录时所设置的 cookie 信息删除那么就可能要重新进行登录认证了。 .1- Set-Cookie 字段与 cookie 文件 cookie 技术可以在第一次认证登录后让后续所有的认证都变成自动认证 。 在第一次登录某个网站时一般都需要输入账号和密码进行身份认证如果服务器经过数据比对后判定登录的用户是合法的且为了之后用户在进行某些网页请求时不必重新输入账号和密码服务器就会进行 Set-Cookie也是 HTTP 报头当中的一种属性信息 的设置。 通过认证并设置好 Set-Cookie 后等服务器需要对浏览器进行 HTTP 响应时服务器就会将设置好的 Set-Cookie 响应给浏览器。浏览器收到响应后会自动提取出 Set-Cookie 的值并将其保存在浏览器的 cookie 文件中相当于将账号和密码信息都保存在本地浏览器的 cookie 文件中。 至此浏览器再次向网站发起的 HTTP 请求中就会自动包含一个 cookie 字段其中携带的就是第一次登录的认证信息。对端服务器能够直接提取出 HTTP 请求中的cookie字段使用户在进行某些网页请求时不必重新输入账号和密码。 cookie 其实就是在浏览器中的一个小文件其中记录了用户的私有信息。 cookie 文件一般分为两种一种是内存级别的 cookie 文件另一种是文件级别的 cookie 文件。 关闭浏览器再打开访问之前登录过的网站如果需要重新输入账号和密码则说明之前登录时浏览器保存的 cookie 信息是内存级别的。将浏览器关掉甚至将电脑重启再打开访问之前登录过的网站如果不需要重新输入账户和密码则说明之前登录时浏览器保存的 cookie 信息是文件级别的。 .2- cookie 被盗与 SessionID cookie 被盗其实说明的是 cookie 信息与其所涉及的用户身份之间的关系。 如果一个用户浏览器中保存的cookie信息被另一个非法用户盗取了那么非法用户就可以通过用户的 cookie 信息以用户的身份去访问用户曾经访问过的网站。 因此单纯地使用 cookie 并不安全。 为了避免 cookie 文件泄漏其中的私密信息也连带着泄漏当前主流的服务器引入了 SessionID 这样的概念。 在第一次登录某个网站时服务器认证成功后还会生成一个对应的 SessionID在进行HTTP 响应时会将这个生成的 SessionID 的值响应给浏览器然后浏览器会将其保存在自己的cookie文件中使后续访问服务器时发起的 HTTP 请求中自动携带上这个 SessionID以辨识用户是否曾经登录过。 这个 SessionID 与用户信息并不相关所有登录用户的 SessionID 会由系统来统一维护。 在引入 SessionID 之前用户登录的账号信息都是保存在浏览器内部的账号信息是由客户端去维护的引入 SessionID 后用户登录的账号信息是由服务器去维护的在浏览器内部保存的只是 SessionID。 在引入 SessionID 之后虽然浏览器中的 cookie 文件保存的是 SessionID 而不再是账户密码了但 SessionID 仍然可能会因 cookie 文件被盗取而被盗取非法用户仍可以通过盗取到的 SessionID 去访问其他用户曾经访问过的服务器。 虽然没有真正解决安全问题SessionID 仍有可能因 cookie 文件被盗而被盗但服务器已经使用各种各样的策略来保护用户账号已经是相对安全的了。 可以通过IP地址的类别来判断登录用户所在的地址范围。如果一个账号在短时间内登录地址发送了巨大变化服务器就会立马识别到这个账号发生异常了然后清除对应的SessionID的值。此时非法用户或原本的用户想要访问服务器就都需要重新输入账号和密码进行身份认证。当用户重新认证登录后服务器还可以将另一方识别为非法用户进而对该非法用户进行对应的黑名单/白名单认证。进行某些高权限的操作时要求操作者再次输入账号和密码信息再次确认身份。有了 SessionID 非法用户就无法在短时间内获取账户密码如果在修改密码时仍需要输入旧密码那么非法用户就无法在短时间内修改原本的密码用户还可以通过追回的方式让当前的 SessionID 失效让操作者重新进行登录认证。SessionID 也有过期策略。例如如果 SessionID 是一个小时内是有效的即便被盗取了也仅仅是在一个小时内有效且在功能上受约束这样就不会造成太大的影响。 【补】网络中信息的安全是相对的         互联网上并不存在绝对的信息安全任何信息安全都是相对的就算将发送到网络中的信息进行加密也存在被人破解的可能。         除非某个信息的破解成本已经远大于破解后的收益也就是说破解这个信息是赔本的那才可以说这个信息是安全的。 .补- 实验演示 Set-Cookie 字段 如果服务器给浏览器的 HTTP 响应当中包含 Set-Cookie 字段那么浏览器再次访问服务器时就会携带上这个 cookie 信息。 此处对于上文的服务器代码在服务器的响应报头中添加一个 Set-Cookie 字段以验证浏览器第二次发起 HTTP 请求时会带上这个添加的 Set-Cookie 字段。 http_server.cc #include iostream #include fstream #include string #include cstring #include unistd.h #include sys/wait.h #include sys/socket.h #include sys/types.h #include netinet/in.h #include arpa/inet.h using namespace std;#define PAGE index.html //网站首页int main() {//1.创建套接字int listen_sock socket(AF_INET, SOCK_STREAM, 0);if (listen_sock 0){cerr socket error! endl;return 1;}//2.绑定struct sockaddr_in local;memset(local, 0, sizeof(local));local.sin_family AF_INET;local.sin_port htons(8888); //绑定端口号为 8888local.sin_addr.s_addr htonl(INADDR_ANY);if (bind(listen_sock, (struct sockaddr*)local, sizeof(local)) 0){cerr bind error! endl;return 2;}//3.监听if (listen(listen_sock, 5) 0){cerr listen error! endl;return 3;}//4.运行struct sockaddr peer;memset(peer, 0, sizeof(peer));socklen_t len sizeof(peer);while(1){//爷爷进程负责获取 HTTP 请求int sock accept(listen_sock, (struct sockaddr*)peer, len);if (sock 0){cerr accept error! endl;continue;}//爸爸进程负责创建孙子进程并退出if (fork() 0){ close(listen_sock);if (fork() 0){ exit(0);}//孙子进程//读取和打印 HTTP 请求char buffer[1024];recv(sock, buffer, sizeof(buffer), 0); cout [ http request begin ] endl endl;cout buffer endl;cout [ http request end ] endl endl;//读取index.html文件ifstream in(PAGE);if (in.is_open()){in.seekg(0, in.end);int len in.tellg();in.seekg(0, in.beg);char* file new char[len];in.read(file, len);in.close();//构建 HTTP 响应string status_line http/1.1 200 OK\n; string response_header Content-Length: to_string(len) \n; //响应报头//在响应报头中添加 Set-Cookie 字段response_header Set-Cookie: NeeEk0\n;string blank \n; string response_text file; string response status_line response_header blank response_text; //响应报文//响应 HTTP 请求send(sock, response.c_str(), response.size(), 0);delete[] file;}close(sock);exit(0);}close(sock);waitpid(-1, nullptr, 0); }return 0; }index.html  !DOCTYPE html html langen headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleTestPOST/title /head bodyh1Hello HTTP/h1p /* 段落部分 *//pform nameinput action/a/b/c methodGETUsername: input typetext nameuserbr/Password: input typepassword namepwd br/input typesubmit valueSubmit/form /body /html 浏览器访问“云服务器 IP 端口号”输入账户密码后点击提交         服务器效果         此时浏览器的第二次 HTTP 请求会携带这个 cookie 信息。 三、HTTPS 协议 1HTTPS 与 HTTP 在计算机行业早期很多公司所使用的应用层协议都是 HTTP。但 HTTP 无论是用 GET 方法传参还是 POST 方法传参数据都是没有经过任何加密的使得很多信息可以通过抓包工具获取到。于是为了解决这个安全问题后来就出现了 HTTPS 协议。 HTTPS 在应用层和传输层协议之间增加了一层加密层SSL TLS本身也是属于应用层的在交付数据时先把数据交给加密层由加密层对数据加密后再交给传输层以此完成对用户的个人信息进行各种程度的加密通信双方使用的应用层协议需一致对端的应用层也要使用 HTTP当对端的传输层收到数据后会先将数据交给加密层由加密层对数据进行解密后再将数据交给应用层以此完成对用户的个人信息的解密。 数据只有在应用层没有被加密的而在应用层往下和网络中都是加密的这就是 HTTPS 协议的作用。 2对称加密与非对称加密 一般地加密的方式可以分为两种 对称加密采用单钥密码系统的加密方法同一个密钥可以同时用作信息的加密和解密。非对称加密采用公钥和私钥来进行加密和解密用其中一个密钥进行加密就必须用另一个密钥进行解密。 【Tips】对称加密         由于对称加密一般比非对称加密效率更高因此双方在正常通信时一般也使用的是对称加密。         进行对称加密通信需要加密方把密钥给解密方使解密方可以对数据正常进行解密但密钥本身也是数据也是需要加密的这反而就变成了鸡生蛋还是蛋生鸡的问题了因此在刚开始进行密钥协商的时候就需要用到非对称加密了。 通信双方建立连接的时候可以协商好加密算法并在服务端去形成非对称加密时使用的公钥和私钥、在客户端去形成对称加密时使用的密钥。在非对称加密中数据用公钥加密就必须用私钥解密而只有服务端才有私钥其他客户端都只有公钥因此客户端用公钥加密后的密钥只有服务器能够解密。生成好公钥、私钥、密钥后服务端会将公钥交给客户端这个公钥全世界都可以看到客户端会用这个公钥对客户端形成的密钥进行加密然后将加密后的密钥发送给服务端服务端拿到后再用私钥进行解密就可以拿到客户端的密钥且其他人是不知道的这个密钥。至此客户端和服务端就可以进行对称加密通信了。         对称加密中最典型的例子就是异或运算。例如用 A 异或 B 就能得到一个中间值 C而又用 C 异或 B 就能重新得到 A 。其中A 就相当于双方的通信数据B 就相当于对称加密中的密钥C 就相当于被密钥加密后的数据。
http://www.pierceye.com/news/322399/

相关文章:

  • 全景旅游网站项目建设湖南建筑公司网站
  • 做网批那个网站好免费视频素材库app
  • cms建站模板appseo网络优化是什么工作
  • 云落wordpress优化大师在哪里
  • 威海网站建设公司手机网站做落地页
  • 海宁建设局网站三网合一 网站建设
  • 1688货源网官方网站网站怎么做背景
  • 做阿里还是网站中小企业为什么要建设网站
  • 天津的网站建设做网站费用怎么入账
  • 网站原型是产品经理做wordpress手机上用的
  • 专业网站排名优化重庆广告公司电话
  • 在线免费看影视网站正规企业展厅设计公司
  • 励志网站织梦源码做电子杂志用什么网站
  • 电子设计网站wordpress数据清除
  • 义乌网站推广中国住房和城乡建设厅网站
  • 濮阳seo网站建设商贸公司寮步网站建设
  • 百姓网网站建设如何在社交网站做销售
  • 网站微信认证费用介绍网络营销的短文
  • 北京微网站修改wordpress后台登陆
  • 网站建设管理工作情况报告企业在线
  • ps临摹网站营销型网站传统网站
  • 对电子商务网站建设和管理的理解学网站开发应该学什么软件
  • 建设网站的app英文成品网站模板下载
  • 破解版软件下载网站网站图片处理方案
  • 安徽网站建设方案服务汉中建设工程招标网
  • 网站建设公司企业模板下载阿里巴巴官网国际站
  • icp备案网站信息修改百度小说排行榜总榜
  • 崇明专业网站建设做网站后台要学什么
  • 专门做搜索种子的网站有哪些吉林平台网站建设多少钱
  • seo网站优化案例高端品牌裙子