复习基础知识. TCP/IP以及HTTP是计算机网络以及互联网开发的基础.
相关书籍:Kunlun/PDF at master · wengjianhong/Kunlun
Linux命令查看:Linux man pages online
TCP/IP
TCP/IP 是用于因特网 (Internet) 的通信协议。计算机通信协议是对那些计算机必须遵守以便彼此通信的的规则的描述。
TCP/IP 是供已连接因特网的计算机进行通信的通信协议。
TCP/IP 指传输控制协议/网际协议(Transmission Control Protocol Internet Protocol)。
TCP/IP 定义了电子设备(比如计算机)如何连入因特网,以及数据如何在它们之间传输的标准
通过数据链路层和传输层的数据都有限制,如图. 在传输层不能超过TCP最大报文段长度(MSS). 比如一次写入大于MSS的数据,再加上HTTP头部信息,超过了MSS后在传输层会将这些信息分段.
每个层会加上头部或头尾部
TCP/IP协议栈属于操作系统(内核态)的行为,
应⽤程序(浏览器)通过调⽤ Socket 库,来委托协议栈⼯作。协议栈的上半部分有两块,分别是负责收发 数据的 TCP 和 UDP 协议,这两个传输协议会接受应⽤层的委托执⾏收发数据的操作。
用户态通过使用socket库结合对应HTTP协议搭建应用程序
传输层TCP协议
TCP数据包格式
⾸先,源端⼝号和⽬标端⼝号是不可少的,如果没有这两个端⼝号,数据就不知道应该发给哪个应⽤.
接下来有包的序号,这个是为了解决包乱序的问题。 还有应该有的是确认号,⽬的是确认发出去对⽅是否有收到.(超时重传,通过定时器和确认序号ack)
如果没有收到就应该重新发送,直到送达, 这个是为了解决丢包的问题。 接下来还有⼀些状态位。例如 SYN 是发起⼀个连接, ACK 是回复, RST 是重新连接, FIN 是结束连接等。TCP 是⾯向连接的,因⽽双⽅要维护连接的状态,这些带状态位的包的发送,会引起双⽅的状态 变更。 还有⼀个重要的就是窗⼝⼤⼩.(面向连接)
TCP 要做流量控制,通信双⽅各声明⼀个窗⼝(缓存⼤⼩),标识⾃⼰当前能够的处理能⼒,别发送的太快,撑死我,也别发的太慢,饿死我。 除了做流量控制以外.(流量控制,通过窗口大小的滑动窗口机制)
TCP还会做拥塞控制,对于真正的通路堵⻋不堵⻋,它⽆能为⼒,唯⼀能做的就是控制⾃⼰,也即控制发送的速度(TCP采用了几种算法来动态地调整发送速率以适应网络状况).
- 流量控制专注于匹配发送方与接收方之间的处理能力,防止发送方发送超出接收方处理能力的数据量。
- 拥塞控制则着眼于整个网络的状态,试图找到合适的发送速率,既不过度占用网络资源导致拥塞,也不过于保守浪费带宽。
- 慢启动(Slow Start)
当一个TCP连接开始时,发送方不知道网络的状态,也不知道接收方能够接受数据的速度。慢启动阶段通过指数增长的方式逐渐增加拥塞窗口(Congestion Window, cwnd)的大小,以便探测网络的容量。初始时,cwnd通常设置为一个小值(如1个最大段大小MSS)。每成功接收到一个ACK确认,cwnd就增加一个MSS。这个过程持续到遇到首个丢包事件或者达到慢启动阈值(ssthresh)。
- 拥塞避免(Congestion Avoidance)
一旦cwnd的值达到或超过ssthresh,TCP进入拥塞避免阶段。在这个阶段,cwnd的增长速度变缓,采用线性增长方式,即每次往返时间(RTT)只允许cwnd增加一个MSS/cwnd。这有助于更精细地探测网络的最大吞吐量,而不会像慢启动那样迅速使网络过载。
- 快速重传(Fast Retransmit)
快速重传机制用于在未超时的情况下检测到丢包。如果发送方连续收到三个对同一数据段的重复ACK,这意味着该数据段可能已经丢失,发送方将立即重传丢失的数据段,而不是等待定时器超时。这样做可以更快地恢复丢失的数据包,减少等待时间。
- 快速恢复(Fast Recovery)
快速恢复与快速重传配合使用。当发送方由于收到三次重复ACK而触发快速重传后,它会进入快速恢复状态。在此状态下,发送方不执行慢启动,而是调整ssthresh到当前cwnd的一半,并从那里继续尝试增大cwnd,直到不再收到重复的ACK为止。这有助于快速从丢包中恢复,而不必回到慢启动状态。
连接时三次握手
这个所谓的「连接」,只是双⽅计算机⾥维护⼀个状态机,在连接建⽴的过程中,双⽅的状态变化时序图
在 HTTP 传输数据之前,⾸先需要 TCP 建⽴连接,TCP 连接的建⽴,通常称为三次握⼿。
三次握⼿⽬的是保证双⽅都有发送和接收的能⼒。
使用netstat -antp,查看tcp连接状态
网络层IP协议
TCP 模块在执⾏连接、收发、断开等各阶段操作时,都需要委托 IP 模块将数据封装成⽹络包发送给通信对象
因为 HTTP 是经过 TCP 传输的,所以在 IP 包头的协议号,要填写为 TCP。 06 (⼗六进制),表示协议为TCP
在 Linux 操作系统,可以使⽤ route -n 命令查看当前系统的路由表
IP数据包包括首部长度和总长度. 此外当IP数据包大于底层协议所允许的大小(MTU)时进行分片.
IP分片的主要特点:
- 标识(Identification):所有分片都共享相同的标识值,以便目标主机可以识别这些分片属于同一个原始数据报。
- 标志(Flags):包含三个比特位,其中两个用于控制是否还有更多的分片以及是否允许分片。
- 片偏移(Fragment Offset):表示该分片在原始数据报中的位置,帮助接收端按照正确的顺序重组数据报。
分片过程
- 当一个IP数据包准备发送时,如果其大小超过了出站接口的MTU,则需要进行分片。
- 每个生成的分片都将包含源地址、目的地址、标识字段和标志字段等信息。
- 除了最后一个分片外,其他所有分片都将填充到它们的最大长度,而最后一个分片可能小于最大长度。
- 接收方收到所有分片后,根据标识字段、标志字段和片偏移字段重组原始数据报
⽣成了 IP 头部之后,接下来⽹络包还需要在 IP 头部的前⾯加上 MAC 头部。在 MAC 包头⾥需要发送⽅ MAC 地址和接收⽅⽬标 MAC 地址,⽤于两点之间的传输。 ⼀般在 TCP/IP 通信⾥,MAC 包头的协议类型只使⽤: 0800 : IP 协议 0806 : ARP 协议
当不知道MAC地址时,需要 ARP 协议帮我们找到路由器的 MAC 地址。
ARP 协议会在以太⽹中以⼴播的形式,对以太⽹所有的设备喊出:“这个 IP 地址是谁的?请把你的 MAC 地址告诉我”。 然后就会有⼈回答:“这个 IP 地址是我的,我的 MAC 地址是 XXXX”。
如果对⽅和⾃⼰处于同⼀个⼦⽹中,那么通过上⾯的操作就可以得到对⽅的 MAC 地址。然后将这 个 MAC 地址写⼊ MAC 头部,MAC 头部就完成了。
操作系统会把本次查询结果放到⼀块叫做 ARP 缓存的内存空间留着以后⽤,不过缓存的时间 就⼏分钟。 也就是说,在发包时: 先查询 ARP 缓存,如果其中已经保存了对⽅的 MAC 地址,就不需要发送 ARP 查询,直接使⽤ ARP 缓存中的地址。 ⽽当 ARP 缓存中不存在对⽅ MAC 地址时,则发送 ARP ⼴播查询。
⽹络包只是存放在内存中的⼀串⼆进制数字信息,没有办法直接发送给对⽅。因此需要将数字信息 转换为电信号,才能在⽹线上传输,也就是说,这才是真正的数据发送过程。 负责执⾏这⼀操作的是⽹卡,要控制⽹卡还需要靠⽹卡驱动程序。 ⽹卡驱动获取⽹络包之后,会将其复制到⽹卡内的缓存区中,接着会在其开头加上报头和起始帧分界符, 在末尾加上⽤于检测错误的帧校验序列
HTTP
HTTP是应用层协议,类似的应用层协议有FTP,SFTP,TELNET等. HTTP协议对于请求报文和响应报文有不同的格式要求. HTTP版本有1.0,1.1与2.0.
进一步
IPV4与IPV6
RPC与HTTP
- RPC(Remote Procedure Call,远程过程调用):是一种协议,允许一个程序通过网络请求另一个地址空间中的子程序或服务,而无需了解底层网络细节。它旨在让开发者像调用本地函数一样调用远程服务。
- HTTP(Hypertext Transfer Protocol,超文本传输协议):是一个用于传输超媒体文档的应用层协议,主要用于Web浏览器与Web服务器之间的通信。尽管最初设计是为了支持网页浏览,但HTTP也被广泛应用于构建RESTful API等服务接口
HTTP与HTTPS
- HTTP 是超⽂本传输协议,信息是明⽂传输,存在安全⻛险的问题。HTTPS 则解决 HTTP 不安全的缺 陷,在 TCP 和 HTTP ⽹络层之间加⼊了 SSL/TLS 安全协议,使得报⽂能够加密传输。
- HTTP 连接建⽴相对简单, TCP 三次握⼿之后便可进⾏ HTTP 的报⽂传输。⽽ HTTPS 在 TCP 三次 握⼿之后,还需进⾏ SSL/TLS 的握⼿过程,才可进⼊加密报⽂传输。
- 两者的默认端⼝不⼀样,HTTP 默认端⼝号是 80,HTTPS 默认端⼝号是 443。
- HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的
HTTPS 在 HTTP 与 TCP 层之间加⼊了 SSL/TLS 协议,可以解决安全⻛险: 信息加密:交互信息⽆法被窃取,但你的号会因为「⾃身忘记」账号⽽没。 校验机制:⽆法篡改通信内容,篡改了就不能正常显示,但百度「竞价排名」依然可以搜索垃圾⼴ 告。 身份证书:证明淘宝是真的淘宝⽹,但你的钱还是会因为「剁⼿」⽽没。
相关网站
代码随想录、阿秀、labuladong、小林coding、JavaGuide