Java网络原理初识——原理、分层模型与一次HTTP请求的全链路

一、网络的演进

独立模式:早期计算机各为其主,数据交换靠"软盘拷贝",效率极低

网络互联:为了共享软件与数据,多台计算机通过计算机传输介质(网线/光纤/电磁波)连接,实现了网络数据传输,即网络通信。

根据覆盖范围,我们将其划分为:

局域网(LAN):局部私有网络,特点是宽带高、延迟低,但广播域比较大时易产生广播风暴。

广域网(WAN):通过路由器将多个LAN互联,覆盖城市甚至全球。互联网就是最大的公共广域网。

二、网络通信的三大基石:IP、端口、协议

要实现跨主机的进程间通信,必须解决"找得到、交的准、读得懂"三个问题。

2.1 IP地址:定位主机(逻辑地址)

作用:标识网络中的主机或网络设备

格式:32位二进制,点分十进制(如127.0.0.1)

本质:IP地址是逻辑上的,它可以随网络环境改变(如手机从WiFi切换到5G,IP即变)。路由器只认IP网段,据此进行路由决策。

2.2端口号:定位进程(入口标识)

作用:标识主机内的特定进程

范围:0~65535.其中0~1023为"知名端口"(如HTTP的80、HTTPS的443),由系统占用;

1024~65535供用户进程使用。

痛点:端口是稀缺资源。高并发服务器必须采用端口复用或长连接,否则极易因端口耗尽而拒绝新连接。

2.3协议:规定"语言规范"

作用:规定数据如何封装、如何建立/断开连接、如何纠错。它是异构网络(不同系统、不同硬件)能够互通的基石。

三者的结合:IP:Port唯一定位一个通信端点,协议决定了数据以什么语法解析。

三、五元组:操作系统内核的"精确制导"

当网卡中断将数据包上交,内核依靠五元组将数据包靳准投递给对应的Socket缓冲区,而不是乱塞给其他进程:

|-------|---------------|----------------|
| 五元组要素 | 示例 | 内核用途 |
| 源IP | 127.0.0.1 | 知道数据谁发送的 |
| 源端口 | 54321 | 区分同一主机的不同进程 |
| 目的IP | 14.215.177.39 | 确认是否发给本机 |
| 目的端口 | 80 | 交给Web服务 |
| 协议号 | TCP/UDP | 交给TCP模块还是UDP模块 |

四、为什么必须分层?------解耦与迭代的必然

网络硬件日新月异(从同轴电缆到光纤),软件协议层出不穷。如果不分层,任意底层物理介质的更换都会导致上层应用全部重写。

分层的终级奥义:上层依赖下层的接口,不依赖实现。就像Web应用不需要关心数据是走双绞线还是WiFi,只要操作系统提供稳定的Socket接口即可。

目前核心的两套模型:OSI七层模型(理论)、TCP/IP五层模型(现实)

4.1OSI七层模型

存在于书本的理论知识

|----|-------|----------------------|
| 层级 | 名称 | 核心 |
| 7 | 应用层 | 为用户进程提供网络服务接口 |
| 6 | 表示层 | 数据格式转换、加解密、压缩解压 |
| 5 | 会话层 | 建立/管理/拆除会话连接 |
| 4 | 传输层 | 端到端可靠/不可靠传输(TCP/UDP) |
| 3 | 网络层 | 主机到主机寻址与路由(IP,路由器再此) |
| 2 | 数据链路层 | 相邻节点帧传输与差错校验(交换机在此) |
| 1 | 物理层 | 原始比特流传输(网线在此) |

4.2TCP/IP五层模型

把OSI的上三层合并为应用层,简化实用

|----|-------|------------------|-------------|
| 层级 | 名称 | 核心协议/设备 | 核心 |
| 5 | 应用层 | HTTP、DNS、SMTP | 生成用户数据 |
| 4 | 传输层 | TCP(可靠)、UDP(不可靠) | 进程间数据交付 |
| 3 | 网络层 | IP、ICMP;路由器 | 跨网段寻址与跳转 |
| 2 | 数据链路层 | 以太网协议;交换机 | 同网段设备间数据帧交换 |
| 1 | 物理层 | 双绞线/光纤/电磁波;集线器 | 物理信号传输 |

五、不同网络设备的边界

集线器(Hub):工作在物理层。它看不懂任何协议头,只会把收到的电信号放大广播出去。

交换机(Switch):工作在数据链路层。它能识别MAC地址,并维护MAC地址表进行精确转发。但它看不懂IP地址,无法跨网段传输。

路由器:工作在网络层。它能识别IP地址,根据路由表跳转。但它默认不关心端口号,除非做NAT(网络地址转换)时才被迫扒开TCP/UDP头部。

有了IP,为什么还要MAC?

原因:IP是最终目标(逻辑地址),MAC是下一跳的交通工具(物理地址)。路由器每次转发,都会剥掉旧的MAC头,封装上下一跳的MAC头,但IP头始终不变(除非做NAT)

六、封装与分用概述

封装:应用数据自上而下,每层加一个头部。数据------>段(TCP头+数据)------>数据报(IP头+段)------>帧(MAC头+数据报+帧尾)。

分用:自上而下,每层剥掉对应的头部,根据头部中的"类型/协议"字段,将载荷交给正确的上层模块。

七、实战推演:当你访问百度时,协议栈每一秒在做什么?

模拟协议模型完整工作流程

阶段一:应用层与传输层(TCP套接字的"三次握手"前置)

从协议栈视角看,TCP三次握手是双方操作系统内核针对五元组建立连接状态(PCB,协议控制块)的过程。

1.客户端内核:应用层调用connect()时,内核从临时端口范围中分配一个空闲端口,并构造一个TCP SYN段:

TCP头部关键字段:源端口54321,目的端口80,Seq=随机值,Flags=SYN。

此时,内核将该连接标记为SYN_SENT状态,并启动重传定时器。

2.服务器内核:收到SYN后,服务器内核并非立即交给Nginx,而是在半连接队列(SynQueue)中创建条目,并回复SYN_ACK,当收到第三次ACK后,该连接被移入全连接队列,此时accept系统调用才返回。

阶段二:网络层

当TCP将SYN段交给IP层时,IP层先是查路由表,查找到下一跳。

IP头封装:源IP、目的IP、TTL、协议号

阶段三:数据链路层------ARP解析

IP层只知道要把包发给网关,但以太网帧需要的是MAC地址。怎么把IP转成MAC?这里涉及一次协议栈内部阻塞:

1.内核先去查询ARP缓存表。如果有对应的MAC,直接使用。

2.如果缓存没命中,这个数据包不能立刻发送,内核必须暂停该数据包的发送流程,并在局域网内广播一份ARP请求帧。

3.网关收到ARP请求后,单播回复自己的MAC。此时,数据链路层拿到MAC,缓存表更新,刚才卡住的数据包被重写唤醒,封装帧。

阶段四:路由器转发

当网管路由器从内网接口收到这个帧时,它执行自下而上再自上而下的精密协作:

1.物理层------>链路层:网卡检测到目的MAC是自己,剥掉帧头帧尾,将里面的IP数据报交给内核IP模块。

2.网络层(核心决策):路由器查看IP头中的目的IP,查询自己的路由表,发现匹配外网出口,将IP头中的TTL减一,并重新计算IP头部校验和

3.链路层(MAC地址重写):路由器发现下一跳不在本地局域网,继续用ARP查询MAC,重新封装帧。

总结:数据包在跨越路由器时,IP头基本不变(只减TTL),但MAC头被完全撕掉重写。这就是IP寻址与MAC寻址的配合。

阶段五:目标服务器的精准分用

经过无数个路由器的MAC换皮,最终帧到达百度服务器的网卡,此时开始逆向的分用:

1.链路层:网卡检测目的MAC是本届,剥掉帧头,交给IP模块

2.网络层:IP模块检测目的IP是本机IP,剥掉IP头,看到协议,交给TCP模块。

3.传输层(TCP内核):提取五元组,在建立连接的表中查找五元组,匹配到后,将数据拷贝到该Socket的接收缓冲区。

4.应用层:Nginx进程通过select系统调用被内核唤醒,从缓冲区读取数据。