一. 再谈HTTP再理解

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

比如:

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

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

http的底层一般是基于传输层协议tcp实现的

  1. 浏览器和web服务器三次握手建立TCP连接
  2. 浏览器进行 req (request请求)
  3. 服务器进行 rep (reply响应)
  4. 浏览器和web服务器四次挥手断开TCP连接

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(1)

http是超文本传输协议, 在底层实现中涉及了很多地文本解析

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

request 报文

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(2)

response 报文

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(3)

主要请求方法解释:

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(4)

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

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(5)

再次手写一个便理解的简单的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; }

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(6)

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(7)

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

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(8)

相关视频推荐

《tcp/ip详解卷一》: 150行代码拉开协议栈实现的篇章

网络原理tcp/udp,网络编程epoll/reactor,面试中正经“八股文”

学习地址:C/C Linux服务器开发/后台架构师【零声教育】-学习视频教程-腾讯课堂

需要C/C Linux服务器架构师学习资料加qun812855908获取(资料包括C/C ,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(9)

二. HTTP对比学习HTTPS

HTTPS : 是以安全为目标的HTTP通道, 通俗说就是安全版本的HTTP,

为啥需要HTTPS

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

SSL操作步骤:

  1. 验证服务器端
  2. 允许客户端和服务端选择加密算法和密码, 确保双方都支持
  3. 验证客户端
  4. 使用公钥加密技术来生成共享加密数据
  5. 创建一个加密的SSL连接
  6. 基于该SSL连接传递HTTP请求

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

HTTP和HTTPS的区别如下:
  1. https协议需要 ca申请证书,一般免费的证书较少,因而是需要一定费用的]
  2. http是超文本传输协议,信息是明文传输,https则是具有安全性的SSL加密传输协议
  3. http 和 https使用的是完全不同的连接方式,用的端口也是不一样的。前者是80端口 后者是443端口
  4. http的连接很简单,是无状态的;https协议是由 SSL HTTP协议构建的可进行加密传输,身份认证的网络协议,比http协议安全.
  5. 在OSI模型中,HTTP工作在应用层,而HTTPS工作在传输层

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

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(10)

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

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(11)

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

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(12)

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

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(13)

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

报文分析

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(14)

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

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

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

6位标志位:

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

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

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

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

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

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

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

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(15)

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

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(16)

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

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

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

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

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

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(17)

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

超时重传机制

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(18)

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

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

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

  1. 最理想的情况下, 找到一个最小的时间, 保证 "确认应答一定能在这个时间内返回".
  2. 但是这个时间的长短, 随着网络环境的不同, 是有差异的.
  3. 如果超时时间设的太长, 会影响整体的重传效率;
  4. 如果超时时间设的太短, 有可能会频繁发送重复的包;

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

  1. Linux中(BSD Unix和Windows也是如此), 超时以500ms为一个单位进行控制, 每次判定超时重发的超时 时间都是500ms的整数倍.
  2. 如果重发一次之后, 仍然得不到应答, 等待 2*500ms 后再进行重传.
  3. 如果仍然得不到应答, 等待 4*500ms 进行重传. 依次类推, 以指数形式递增.
  4. 累计到一定的重传次数, TCP认为网络或者对端主机出现异常, 强制关闭连接.
滑动窗口理解

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(19)

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

第一种是ACK丢失

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(20)

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

情况2是数据包传过去的时候就丢失了

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(21)

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

拥塞控制

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(22)

TCP小结

TCP是面向连接的,可靠的,基于字节流的传输层通信协议

如何保证可靠性:

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(23)

性能提升上面:

1. 采取了滑动窗口

2. 快速重传 (不需要等待超时,三次对端提醒之后自动重传)

基于TCP应用层协议 HTTP HTTPS SSH Telnet FTP SMTP

TCP最大连接数的分析(面试常考)(从四元组的角度入手)四.UDP协议

先从报文分析入手

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(24)

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(25)

UDP的特征: 什么是无连接,不可靠,关键为什么它如此的不稳定但是在现在的短视频 音视频通话 DNS ARP这些全部都还使用的是UDP作为传输层协议

首先是无连接, 连接是什么: 连接算是一端到另外一端的不存在的一根线 (抽象的来说,这个是我的个人理解, 连接的过程也就是三次握手的过程)对于三次握手不理解的可以看我前文链接存在详解

首先不论是有连接还是无连接, 我们核心应该确定的是什么? 确定四元组,对了四元组,无连接也可以进程间通信,只不过每一次必须传入四元组, 但是口说无凭, 咱看看接口呗。对比一下:

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(26)

为什么UDP是不可靠连接?

因为UDP没有TCP的哪些为了保证可靠性的机制: 比如超时重传机制,拥塞控制,流量控制机制,为数据包编号排序等...

思考为啥UDP如此不可靠我们还必须要使用它, 而且还会尽量的使其变得可靠, 还要专门做UDP可靠性设计,这个不是多次一举吗. 不如直接使用TCP?

首先解释UDP相比TCP为什么相对实时性好, 在时间上更短, 更加快速。。。

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(27)

以上是从不必要的三次握手建立连接上解释这个速度问题, 为啥UDP更快

而且在进行数据传输的时候TCP还会存在一定的时间限制,时间阈值,超过这个时间就需要进行重传, 重传也会导致延迟性,向我们的qq聊天呀就经常出现这样的延迟现象,很明显底层应当是采取的TCP作为传输层协议.

根据上述的延迟解释一下音视频通话为例解释下为啥使用UDP而不是TCP?

一句话解释:就是通话延迟的问题,我们qq上发个消息是无所谓,延迟下我们可以等会看嘛,但是你在跟别人搞音视频,像抖音这些,或者各种视频,这个要是通话延迟,几秒前说的话几秒后出来了你这个还搞个屁呀, 还说得清嘛,这个很明显需要实时通话,正是这样的场景存在所以UDP必然是需要的。。。而且现在音视频(短视频)如此火爆更是少不了UDP了

我们再从另外一个角度来分析一下这个问题, 服务端压力上面来考虑。。。

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(28)

再谈UDP可靠传输的设计。。。

现有的udp可靠传输协议就是KCP了,感兴趣的还真有必要得去深入研究一下,我个人是研究深度还不够,先暂且浅显的聊一聊这个UDP可靠传输设计的一些基本的东西,KCP要是将来我的理解深入足够会尽力刨析一下...

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(29)

首先既然提到了MTU 先解释一下 MTU是个啥玩也.

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(30)

总结UDP可靠传输的学习:

五. 对比TCP和UDP的细节总结本文

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(31)

http协议处于tcp/ip哪一层(再谈Http和Https及TCPUDPIP协议分析)(32)

,