网络协议报文理解刨析篇二(再谈Http和Https), 加上TCP/UDP/IP协议分析(理解着学习), 面试官都惊讶你对网络的见解(1)

简介: 网络协议报文理解刨析篇二(再谈Http和Https), 加上TCP/UDP/IP协议分析(理解着学习), 面试官都惊讶你对网络的见解(1)

一. 再谈HTTP再理解

协议的本质:  双方的一种约定,规则,双方需要按照相同的一套处理机制(协议)进行处理

应用层协议对应的是一个服务, FTP文件传输协议, NDS域名解析协议, HTTP超文本传输协议, 这些是协议同时也对应着一个服务.

http协议的本质 : http协议的本质是要获得某种资源   (视频,音频, 网页,图片等)

实际上,上网的大部分行为都是在进行进程间通信..  也就是不断地获取信息和发送信息


比如:    


1. 把服务器上面地资源数据拿到本地 (短视频, 网页)


2. 把本地地数据推送到服务器 (搜索, 注册,登录,下单)

  • http的底层一般是基于传输层协议tcp实现的
  1. 浏览器和web服务器三次握手建立TCP连接
  2. 浏览器进行   req   (request请求)
  3. 服务器进行   rep (reply响应)
  4. 浏览器和web服务器四次挥手断开TCP连接
  5. http是超文本传输协议, 在底层实现中涉及了很多地文本解析

再谈http地无状态:  指协议不具备记忆地能力, 不需要对于进程间通信地历史状态进行保存, 服务器是无法判断用户是否历史上曾经打开过这个网页了的. 也就是上一次打开网页和这一次打开相同的网页互相不关联, 也不知道你上次打开过. (不会记忆)这个就叫做无状态


request 报文

  • response 报文

在写HTTP服务器的时候我们必须按照上述的报文格式进行书写


在整个收发请求数据和应答数据报文的时候会进行报文的解析, 之所以每一个结束位置都是一个CRLF,就是回车换行的意思, 所有的信息以一行一行的形式进行呈现出来


空行出现的原因:     作为报头和有效载荷的分割符号.   循环着一行一行的读取, 直到读取到空行代表报头读取完毕


主要请求方法解释:


GET : 直接获取对应的资源信息(eg: 网页) 资源从哪来 URL定位


POST : 将数据交给服务器, 通过正文提交, 不需要URL定位

上述便是需要Content-Length的原因, 获知正文是否存在以及正文长度

  • 再次手写一个便理解的简单的httpserver.cc 的服务器, 使用C++完成
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <strings.h>
#include <signal.h>
#include <string>
#include <fstream>
#define ERR_EXIT(m) \
  do { std::cerr << m << std::endl; close(EXIT_FAILURE); } while(0)
typedef struct sockaddr SA;
int main() {
  signal(SIGCHLD, SIG_IGN);//信号处理, 避免子进程僵尸
  int listenfd, connfd, pid;
  socklen_t addLen;
  struct sockaddr_in clientAdd, serveAdd;
  if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ) {
    ERR_EXIT("socket");
  } 
  int flag = 1;
    setsockopt(listenfd,SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
    //SO_REUSEADDR  BOOL 允许套接口和一个已在使用中的地址捆绑(参见bind())
    //SOL_SOCKET固定level设置
  bzero(&serveAdd, sizeof(serveAdd));//清空
  serveAdd.sin_family = AF_INET;//协议家族
  serveAdd.sin_port = htons(8080);//默认80端口
  serveAdd.sin_addr.s_addr = htonl(INADDR_ANY);
  //INADDR_ANY == 0 作用适配地址
  if (bind(listenfd, (SA*)&serveAdd, sizeof(serveAdd)) == -1) {
    ERR_EXIT("bind");
  }
  //3: 等待队列syn队列的长度
  if (listen(listenfd, 3) == -1) {
    ERR_EXIT("listen");
  }
  while (1) {
    if ((connfd = accept(listenfd, (SA*)&clientAdd, &addLen)) == -1) {
      ERR_EXIT("accept");
    }
    pid = fork();//fork出来子进程
    if (pid) {
      close(connfd);
      //父进程关闭connfd然后仅仅进行listen. SIGCHLD会自动收尸
    } else {
      close(listenfd);//子进程进行发送响应报文
      char buffer[1024];
            recv(connfd, buffer, sizeof(buffer), 0);
            std::cout << "#############################http request begin#############################################"<<std::endl;
            //打印recv的来自客户端的请求并且输出请求信息
            std::cout << buffer << std::endl;
            std::cout << "#############################http request end#############################################"<<std::endl;
            std::ifstream ifs("./index.html");
            if (ifs) {
              int len;
              ifs.seekg(0L, ifs.end);//定位到文件末尾
              len = ifs.tellg();//获取文件长度
              ifs.seekg(0L, ifs.beg);//回到文件开头
              char *file = new char[len];
              ifs.read(file, len);//读取正文, 字符串形式读取
              ifs.close();
              //开始处理响应:
              std::string status_line = "HTTP/1.1 200 OK\r\n";//状态行
              std::string reply_header;//响应头部
              reply_header +="Content-Length: " + std::to_string(len) + "\r\n";
              std::string black = "\r\n";
              send(connfd, status_line.c_str(), status_line.size(), 0);
              send(connfd, reply_header.c_str(), reply_header.size(), 0);
              send(connfd, black.c_str(), black.size(), 0);
              send(connfd, file, len, 0);
              delete [] file;
            }
            close(connfd);
            exit(EXIT_SUCCESS);
    }
  } 
  close(listenfd);
  return 0;
}

服务器IP : 端口号 可以访问, 服务器可能没有开放端口, 可以在购买的服务器安全组中设置

  • 再次图解小结HTTP, 整个协议栈的角度去看

注意:   这个http应用层简单的理解是直接和对端建立了连接好似是直接和对端进行请求响应的交互方式, 然后一次连接完成之后立马断开, 但是其实真正传输数据包的时候, 是需要贯穿整个协议栈的, 也就是http请求是将自己的数据传给下层的, 是有封包和解包的过程的, 不理解可以看入门篇


再强调一下http叫啥: 超文本传输协议, 其实蛮简单的, 就是传输的文本, 文本内容在数据报文的正文中,正文前面有报头请求行(请求), 或者是报头和状态行(响应)....     报头和有效载荷的分离依赖的是空行.


请求行:   请求方法(GET, POST)  URL:资源定位      协议版本(HTTP/1.0   HTTP/1.1 ...)


响应状态行:   协议版本,   状态码   状态码描述信息。。。


中间的各种 键: 值    对(首部字段名: 值) 都是各种细节信息 eg : Content-Length


空行: 分隔报头和有效载荷(正文)

二. HTTP对比学习HTTPS

HTTP的请求信息是明文传输, 容易被窃取


HTTP不会验证对方的信息, 存在被冒充的风险


数据的完整性没有校验, 容易被中间人篡改


为啥叫做HTTPS , S的含义, SSL:加密,在HTTP下加入SSL层  (解决上述问题)


SSL操作步骤:


验证服务器端


允许客户端和服务端选择加密算法和密码, 确保双方都支持


验证客户端


使用公钥加密技术来生成共享加密数据


创建一个加密的SSL连接


基于该SSL连接传递HTTP请求


HTTPS的主要作用:一个是建立一个信息安全通道,用来保证数据传输的安全性,另外一个就是验证网站的真实性了...

HTTP和HTTPS的区别如下:

https协议需要  ca申请证书,一般免费的证书较少,因而是需要一定费用的]


http是超文本传输协议,信息是明文传输,https则是具有安全性的SSL加密传输协议


http 和 https使用的是完全不同的连接方式,用的端口也是不一样的。前者是80端口 后者是443端口


http的连接很简单,是无状态的;https协议是由 SSL + HTTP协议构建的可进行加密传输,身份认证的网络协议,比http协议安全.


在OSI模型中,HTTP工作在应用层,而HTTPS工作在传输层写传输层协议之前先介绍一个四元组的概念:   网络通信的实现就是基于四元组的,不论是TCP还是UDP  要想将数据从一端传入到另外一端,就必须明确对端的二元组, 双方如果都要相互通信就要确定四元组    

首先我们确定要双方不同主机上的不同进程间进行通信, 必须确定双方的 ip + port   why?

  • 上述图主要是为了引出为啥要  ip 

  • 上述图是为了引出为啥需要  port

  • 至此我想聪明的大家自然是明白了为啥一定要确定四元组双发才能通信了
  • 上述四元组可谓是特别重要的一个铺垫了, 后序的TCP最大连接数目等等咱要分析清楚其实都还得必须从上述这个得限制入手了.  (这个也是面试的常考点)

三.TCP协议  (三次握手四次挥手细节过程理解在之前的博文中有详细图解)

  • 报文分析

源  / 目的端口,那就是老身常谈了, 从哪个进程来,到哪个进程去


32位序号和确认序号    (原谅咱留个小疑惑,后面解释,和重传机制有关系)

4位TCP报头长度: 表示该TCP头部有多少个32位bit(有多少个4字节); 所以TCP头部最大长度是15 * 4 = 60   (基本衡量单位都是4字节为最小单位)     因为首部长度是4位 最大就是15; 所以最大首部长度就是  15 * 4 (最小单位) = 60字节


6位标志位:


URG: 紧急指针是否有效


ACK: 确认号是否有效


PSH: 提示接收端应用程序立刻从TCP缓冲区把数据读走


RST: 对方要求重新建立连接; 我们把携带RST标识的称为复位报文段


SYN: 请求建立连接; 我们把携带SYN标识的称为同步报文段


FIN: 通知对方, 本端要关闭了, 我们称携带FIN标识的为结束报文段


16位窗口大小(先留个疑,其实就是存储接收缓冲区还剩下的大小,  和流量控制有关)


16位校验和: 发送端填充, CRC校验. 接收端校验不通过, 则认为数据有问题. 此处的检验和不光包含TCP首部, 也 包含TCP数据部分


6位紧急指针: 标识哪部分数据是紧急数据

tcp缓冲区概念的引入  (解释流量控制):

tcp连接建立之后是存在接收和发送内核缓冲区的....


send 还有 recv这些接口都不是直接将数据发送到网路中,也不是直接从网路中读取数据的...


而是存在发送缓冲区和接收缓冲区的概念, 这些都是内核缓冲区。。。同样之前的窗口大小其实就是接收缓冲区还剩余的大小, 支持流量控制  (你发送的数据不能超过,不然就满了)

  • 接收缓冲区大写也对应着流量控制:why? 如何理解

接收端处理数据的速度是有限的. 如果发送端发的太快, 导致接收端的缓冲区被打满, 这个时候如果发送端继续发送, 就会造成丢包, 继而引起丢包重传等等一系列连锁反应.


因此TCP支持根据接收端的处理能力, 来决定发送端的发送速度. 这个机制就叫做流量控制(Flow Control)      


所以窗口大小就是接收端处理能力的代表  (发送端接收到窗口大小会根据窗口大小进行调节自己的发送速度,进行流量控制)   填充窗口字段就是填充的自身的接收缓冲区中剩余空间的大小    (此窗口也称为接收窗口)


窗口大小字段越大, 说明网络的吞吐量越高;

确认应答(ACK)机制的理解 (编序号)

  • ACK应答的含义就是:   acknum 之前的序号的数据包我都已经收到了,下一次你从acknum开始发送吧

超时重传机制

超时重发指的是因为网络环境的拥堵阻塞导致了在很长一段时间发送方都没有等到自己之前发送包的回音  (于是TCP默认是丢包)然后会采取重传措施


由于重传机制,会存在一些情况是   之前因为网络拥堵的数据包 在网络环境恢复之后正常传入到对端,  导致对端可能会收到多份重复的数据报文,不过嘞因为序号的存在可以通过需要进行简单的去重即可


但是这个超时时间如何确认???  多少算合适,这个也是个置得讨论的问题


最理想的情况下, 找到一个最小的时间, 保证 "确认应答一定能在这个时间内返回".


但是这个时间的长短, 随着网络环境的不同, 是有差异的.


如果超时时间设的太长, 会影响整体的重传效率;


如果超时时间设的太短, 有可能会频繁发送重复的包;


TCP为了保证无论在任何环境下都能比较高性能的通信, 因此会动态计算这个最大超时时间.(抓核心主题,据网络环境而生   超时时间)


Linux中(BSD Unix和Windows也是如此), 超时以500ms为一个单位进行控制, 每次判定超时重发的超时 时间都是500ms的整数倍.


如果重发一次之后, 仍然得不到应答, 等待 2*500ms 后再进行重传.


如果仍然得不到应答, 等待 4*500ms 进行重传. 依次类推, 以指数形式递增.


累计到一定的重传次数, TCP认为网络或者对端主机出现异常, 强制关闭连接.

滑动窗口理解

首先滑动窗口的前提是基于缓冲区来实现的, 没有缓冲区是做不到滑动窗口的,流量控制同样也是做不到的


滑动窗口的出现是根据缓冲区大小来进行一次发送多条数据来提升性能...


可以思考一下反正我需要发很多数据,1 - 1000  1001 - 2000 2001 - 3000 ...  我是可以采取一条一条的发送,等待一条有了回音,再继续发送下一条,可是如果窗口是足够的情况下我可以一次发送多条数据,这样可以将每条数据的等待应答时间重叠起来,实现效率性能的提升...

如同上图这般,同时发送多条数据  (将多条数据的等待应答时间压缩成一条数据的等待应答时间)


窗口大小指的是无需等待确认应答而可以继续发送数据的最大值. 上图的窗口大小就是3000个字节(3个 段).    这个称为发送窗口大小  (是根据所在端的发送缓冲区大小和对端的接收缓冲区的大小中取出最小值来确定的)


发送前四个段的时候, 不需要任何等待,直接可以发送


收到第一个ACK后, 滑动窗口向后移动, 继续发送第五个段的数据; 依次类推


操作系统内核为了维护这个滑动窗口, 需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答; 只有确 认应答过的数据, 才能从缓冲区删掉


窗口越大, 则网络的吞吐率就越高

滑动窗口下的丢包问题分析

  • 第一种是ACK丢失

  • 如上述情况下,滑动窗口的ACK部分丢失其实不是很紧要,因为可以通过后序的ACK确认;ACK一旦确认之后代表的含义是   默认之前的所有序列数据都已经全部收到了
  • 情况2是数据包传过去的时候就丢失了

当某一段报文段丢失之后, 发送端会一直收到 1001 这样的ACK, 就像是在提醒发送端 "我想要的是 1001" 一样


然后; 如果发送端主机连续三次收到了同样一个 "1001" 这样的应答, 就会将对应的数据 1001 - 2000 重新发送;


这个时候接收端收到了 1001 之后, 再次返回的ACK就是7001了(因为2001 - 7000)接收端其实之前就已 经收到了, 被放到了接收端操作系统内核的接收缓冲区中   (提前收到的后序的报文也不会丢弃, 只是前面的没有确认 后面的也就无法确认,因为一旦确认就默认前面的所有数据全部已经收到了)


这种机制被称为 "高速重发控制"(也叫 "快重传").  


单独解释一下 快重传  : 就是说在接收方收到一个失序的报文段的时候就立即会发出重复确认。(目的在于使得发送方尽早地知道说自己有报文丢失了,没有到达对面)接收方地意思就是     哥你确定你发的是对的,我前面的报文都还没收到  (顺序不对呀)三次之后发送方反应过来直接重传,不再等待超时


相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
7月前
|
运维 网络协议 安全
为什么经过IPSec隧道后HTTPS会访问不通?一次隧道环境下的实战分析
本文介绍了一个典型的 HTTPS 无法访问问题的排查过程。问题表现为 HTTP 正常而 HTTPS 无法打开,最终发现是由于 MTU 设置不当导致报文被丢弃。HTTPS 因禁止分片,对 MTU 更敏感。解决方案包括调整 MSS 或中间设备干预。
|
7月前
|
缓存 网络协议 API
HTTP/1.1相较于HTTP/1.0所实现的性能提升点分析。
通过以上的技术改进,HTTP/1.1显著提升了Web的性能和可靠性,同时减少了带宽的使用和服务器的负载。这些特性直到今天仍然是现代Web通信的基础。尽管如今HTTP/2和HTTP/3逐渐取代了旧的协议,以上所述的HTTP/1.1性能提升对所有后续版本仍然有着深远影响。
323 0
|
10月前
|
网络协议 API 开发者
分析http.client与requests在Python中的性能差异并优化。
合理地选择 `http.client`和 `requests`库以及在此基础上优化代码,可以帮助你的Python网络编程更加顺利,无论是在性能还是在易用性上。我们通常推荐使用 `requests`库,因为它的易用性。对于需要大量详细控制的任务,或者对性能有严格要求的情况,可以考虑使用 `http.client`库。同时,不断优化并管理员连接、设定合理超时和重试都是提高网络访问效率和稳定性的好方式。
248 19
|
10月前
|
安全 网络协议 Linux
Linux网络应用层协议展示:HTTP与HTTPS
此外,必须注意,从HTTP迁移到HTTPS是一项重要且必要的任务,因为这不仅关乎用户信息的安全,也有利于你的网站评级和粉丝的信心。在网络世界中,信息的安全就是一切,选择HTTPS,让您的网站更加安全,使您的用户满意,也使您感到满意。
303 18
|
11月前
|
XML JSON 网络协议
利用HTTP POST协议实现简单的RPC协议:WireShark抓包分析
通过这种方式,我们可以使用HTTP POST实现简单的RPC协议,并使用WireShark进行抓包分析。这不仅可以帮助我们理解RPC协议的工作原理,也可以帮助我们调试和优化我们的代码。
610 30
|
10月前
|
数据采集 监控 安全
HTTP代理和IP代理的不同点及代理IP能带来的好处分析
总的来说,无论是HTTP代理还是IP代理,选择哪一种主要还是要看你的需求和使用场景,同时也要为可能的风险做好准备。
246 9
|
11月前
|
JSON 数据格式
利用HTTP POST协议实现简单的RPC协议,并使用WireShark进行抓包分析
通过这种方式,我们可以利用HTTP POST实现简单的RPC协议,并使用WireShark进行抓包分析。这种方式简单易懂,实用性强,可以应用于各种网络编程场景。
479 16
免费HTTP代理IP对业务稳定性的影响关键因素分析
随着互联网发展,使用代理IP的需求增加。免费代理IP虽便捷,但对业务稳定性有负面影响:1. 网络连接不稳定,易中断;2. 频繁更换IP影响业务连续性;3. 性能差,速度慢、响应延迟高;4. 服务质量低,缺乏技术支持且存在不受控的限制。因此,选择代理服务时需谨慎评估其对业务的影响。
487 13
|
安全 算法 网络协议
【网络原理】——图解HTTPS如何加密(通俗简单易懂)
HTTPS加密过程,明文,密文,密钥,对称加密,非对称加密,公钥和私钥,证书加密
|
网络协议 安全 网络安全
探索网络模型与协议:从OSI到HTTPs的原理解析
OSI七层网络模型和TCP/IP四层模型是理解和设计计算机网络的框架。OSI模型包括物理层、数据链路层、网络层、传输层、会话层、表示层和应用层,而TCP/IP模型则简化为链路层、网络层、传输层和 HTTPS协议基于HTTP并通过TLS/SSL加密数据,确保安全传输。其连接过程涉及TCP三次握手、SSL证书验证、对称密钥交换等步骤,以保障通信的安全性和完整性。数字信封技术使用非对称加密和数字证书确保数据的机密性和身份认证。 浏览器通过Https访问网站的过程包括输入网址、DNS解析、建立TCP连接、发送HTTPS请求、接收响应、验证证书和解析网页内容等步骤,确保用户与服务器之间的安全通信。
934 3

热门文章

最新文章