网络基础概念

网络基础概念

计算机网络是现代信息世界的基石,但初学时面对一堆术语常感混乱。本篇将以通俗易懂且不失深度的方式,细致整理总结网络中最重要的基本概念,并串联起两台主机通信的完整流程,深入到协议字段和内核行为~~


一、核心角色:客户端与服务器

客户端(Client)

主动发起通信的一方。通常是运行在用户设备上的应用程序。除了我们熟知的浏览器、App,还包括系统更新服务、NTP时间同步客户端等。客户端的特点是:

  • 动态端口:发起连接时,操作系统会临时分配一个未被占用的端口号(如 54321),称为"临时端口"。

  • 地址不固定:客户端的IP地址可能是动态分配的(DHCP),也可以是内网地址(NAT转换后上网)。

  • 主动关闭:通信结束后,通常由客户端先发起关闭连接的请求(TCP四次挥手由客户端先发FIN)。

服务器(Server)

被动等待连接并提供服务的一方。其特点是:

  • 监听固定端口 :如 Web 服务器监听 80/443,MySQL 监听 3306。服务程序启动后会调用 bind()listen() 系统调用,让操作系统内核在该端口上等待。

  • 高并发模型:一个服务器通常要同时服务成千上万个客户端。单靠一个进程无法处理,因此演化出多进程、多线程、I/O多路复用(select/epoll)等并发模型。

  • 反向代理与负载均衡:在实际大型网站中,客户端直接连接的"服务器"往往是Nginx这样的反向代理,真正的应用服务器藏在后端。这也是C/S模型的扩展。

打个比方:客户端像顾客,服务器像餐厅。但餐厅不仅有前台(反向代理),后厨(应用服务器)和前厅是分离的,前台负责接待并转发需求给后厨,这样后厨可以专注做菜,前厅负责应对高流量。


二、地址与标识:IP地址与端口号(深入协议字段)

IP地址

IPv4 地址详解

一个 IPv4 地址共 32 位,通常用点分十进制表示,如 192.168.1.1。实际上它包含两部分:

  • 网络号:标识主机所在的网络(子网)。

  • 主机号:标识该网络内的具体设备。

如何划分网络号和主机号?靠子网掩码 。例如 255.255.255.0 表示前 24 位是网络号,后 8 位是主机号。无类域间路由(CIDR)记法为 192.168.1.1/24

特殊IP地址

  • 127.0.0.1:本地环回地址,数据不经过网卡,直接在内核协议栈中转回本机。

  • 0.0.0.0:在本机表示所有IP地址,服务器监听 0.0.0.0:80 意味着接受来自任何网卡的连接。

  • 255.255.255.255:受限广播地址,发给同一物理网络中的所有主机。

公网IP与私网IP(NAT)

由于IPv4地址枯竭,家庭和公司内部普遍使用私有地址(如 10.x.x.x172.16.x.x192.168.x.x)。内网主机访问公网时,路由器执行 网络地址转换(NAT) :将数据包中的源IP替换为路由器的公网IP,并记录映射表,收到响应后再根据端口转换回内网IP。这就是为什么你查看自己IP是 192.168.1.x,而百度搜IP显示的是另一个公网地址。

IPv6 简介

IPv6 使用 128 位地址,号称能为地球上每一粒沙子分配IP。格式如 2001:0db8:85a3:0000:0000:8a2e:0370:7334,可以省略前导零和连续零块。IPv6 没有了广播,使用组播和任播,同时原生支持IPSec。

端口号

端口号是一个 16 位无符号整数,范围 0~65535。在 TCP/UDP 协议头部中占据 16 位空间(所以最大就是 65535)。

  • 知名端口(0-1023):只有 root/管理员权限才能绑定监听。例如 22(SSH)、80(HTTP)、443(HTTPS)。

  • 注册端口(1024-49151):分配给特定服务,但普通用户也可绑定。如 3306(MySQL)、5432(PostgreSQL)。

  • 动态/私有端口(49152-65535):操作系统自动分配给客户端程序使用。

端口与Socket

网络编程中常说"Socket",它其实是一个五元组:
(源IP, 源端口, 目的IP, 目的端口, 协议)

只要五元组中任一元素不同,就是不同的Socket连接。这就是为什么服务器一个端口(如80)可以同时服务成千上万个客户端------因为客户端的源IP或源端口不同,五元组唯一区分了每条连接。

比喻:IP地址是写字楼地址,端口号是办公室门牌号。但要注意,一栋楼里可能有多个同名的"财务部"(比如多个公司共用大楼),区分它们需要同时知道大楼地址+房间号。在网络中就是 IP + 端口。


三、通信规则:协议与协议分层

协议

协议不仅仅是"约定",在实现上它是定义在RFC(Request for Comments)文档中的结构化字节流规范 。例如 HTTP/1.1 协议规定请求行必须包含方法、URI和版本,以 \r\n 换行。协议通常包含三要素:

  1. 语法:数据格式、编码、信号电平。

  2. 语义:控制信息(如状态码200的含义)、差错处理。

  3. 时序:顺序、速率匹配。

协议分层

我们以实际应用最广的 TCP/IP五层模型(物理层、数据链路层、网络层、传输层、应用层)来详细拆解,并指出每一层的数据单元名称和关键头部字段。

1. 物理层
  • 功能:定义物理设备标准,如网线接口形状、电压高低、光波长、无线频率、比特流传输速率。

  • 数据单元:比特(bit)。

  • 常见设备:中继器、集线器、光纤收发器。

  • 不关心:数据内容,只负责把0/1准确传过去。

2. 数据链路层
  • 功能 :在相邻节点 之间(同一局域网或点对点链路)提供可靠的数据传输。负责物理寻址 (MAC地址)、差错检测流量控制(部分协议)。

  • 数据单元:帧(Frame)。

  • 协议举例:以太网(Ethernet)、Wi-Fi(802.11)、PPP。

  • 以太网帧结构(详细):

    • 前导码(7字节+1字节起始定界符):用于时钟同步。

    • 目的MAC地址(6字节):下一跳接收设备的物理地址。

    • 源MAC地址(6字节):本机出口网卡的物理地址。

    • 类型/长度 (2字节):0x0800 表示上层是IPv4,0x0806 表示ARP。

    • 数据(46-1500字节):来自网络层的IP数据报。

    • 帧校验序列FCS(4字节):CRC32校验,接收端计算校验和与尾部对比,不一致则丢弃帧。

  • MAC地址 :48位,全球唯一(理论上),通常用十六进制冒号分隔,如 00:1A:2B:3C:4D:5E。前24位是厂商OUI,后24位由厂商分配。

3. 网络层
  • 功能 :负责跨网络的路径选择(路由)和逻辑寻址(IP地址)。将数据从源主机通过多个路由器送达目标主机。提供尽力而为的不可靠传输(IPv4)。

  • 数据单元:数据报(Datagram),有时称IP包。

  • 核心协议:IP(IPv4、IPv6)、ICMP(ping所用)、ARP(地址解析协议,介于链路和网络层)、OSPF/RIP/BGP(路由协议)。

  • IPv4头部关键字段(20字节固定+可选):

    • 版本(4位):4或6。

    • 首部长度(4位):以4字节为单位,最小5(20字节)。

    • 服务类型TOS(8位):用于QoS优先级。

    • 总长度(16位):首部+数据的字节数,最大65535。

    • 标识、标志、片偏移:用于IP分片重组。

    • 生存时间TTL(8位):每经过一个路由器减1,到0丢弃。防止包在网络中死循环。

    • 协议 (8位):6表示TCP,17表示UDP,1表示ICMP。

    • 首部校验和(16位):只校验首部,出错丢弃。

    • 源IP地址(32位)。

    • 目的IP地址(32位)。

  • ARP协议工作细节:当主机A(192.168.1.10)想发送数据给同网段主机B(192.168.1.20)时:

    1. A查ARP缓存,没有B的MAC。

    2. A发送ARP请求广播帧(目的MAC全F),内容:"谁是192.168.1.20?告诉我你的MAC"。

    3. B收到后,回复ARP应答单播帧,告知自己的MAC。

    4. A将IP数据报封装进帧,目的MAC填B的MAC,发出。

4. 传输层
  • 功能 :提供端到端(进程到进程)的数据传输服务。可以弥补网络层的不可靠性(如TCP),也可以保持精简(如UDP)。负责分段、流量控制、差错控制、拥塞控制。

  • 数据单元:报文段(Segment,TCP)或数据报(Datagram,UDP)。

  • TCP协议深入

    • 面向连接:通信前必须三次握手建立连接。

    • 可靠传输:确认应答ACK、超时重传、滑动窗口流量控制。

    • TCP头部关键字段(20字节):

      • 源端口、目的端口(各16位)。

      • 序列号Seq(32位):标识本报文段发送的数据第一个字节的序号。初始序列号ISN随机生成。

      • 确认号Ack(32位):期望收到对方下一个报文段的Seq。

      • 数据偏移(4位):TCP首部长度。

      • 标志位 (6位):URG、ACK 、PSH、RST、SYNFIN

      • 窗口大小(16位):用于流量控制,告知对方还能接收多少字节。

      • 校验和(16位):校验首部和数据部分,计算时包含伪首部(取自IP头的源/目的IP)。

      • 紧急指针(16位)。

    • 三次握手简析

      1. 客户端 → 服务器:SYN=1, Seq=x

      2. 服务器 → 客户端:SYN=1, ACK=1, Seq=y, Ack=x+1

      3. 客户端 → 服务器:ACK=1, Seq=x+1, Ack=y+1

        握手过程协商了初始序列号、MSS、窗口大小等参数。

  • UDP协议:无连接、不可靠,但头部仅8字节(源端口、目的端口、长度、校验和),适合实时应用(语音、视频、DNS查询)。

5. 应用层
  • 功能:为应用程序提供网络服务接口。定义具体应用的数据格式和交互逻辑。

  • 数据单元:报文(Message)。

  • 协议举例:HTTP/HTTPS、FTP、SMTP、DNS、SSH。

  • HTTP/1.1 请求报文结构

    • 请求行:GET /index.html HTTP/1.1\r\n

    • 头部字段:Host: www.example.com\r\nUser-Agent: ...\r\n

    • 空行:\r\n

    • 可选正文:POST请求的数据。

  • DNS解析细节 :浏览器访问 www.example.com 时,先检查本地hosts和DNS缓存,若无则向本地域名服务器(通常是路由器或运营商)发起递归查询。本地域名服务器可能进行迭代查询:根域名服务器 → .com顶级域服务器 → example.com权威服务器,最终返回IP。


四、封装与分用

封装(Encapsulation)详细过程(以TCP发送为例)

假设应用层要发送一个HTTP响应,大小为3000字节。经过传输层TCP时:

  1. 传输层封装(分段)

    • TCP根据路径MTU(最大传输单元,通常1500字节减去IP/TCP首部)和MSS(最大分段大小,约1460字节),将3000字节应用数据分成3个TCP段。

    • 为每个段添加TCP头部。例如第一个段:Seq=1001,数据长度1460。第二个段:Seq=2461,数据长度1460。第三个段:Seq=3921,数据长度80。

    • 将TCP段交给网络层。

  2. 网络层封装

    • IP层收到TCP段后,添加IP头部。此时数据总长度为 20(IP头)+ 20(TCP头)+ 1460(数据)= 1500字节。

    • 如果IP包长度超过链路MTU(如以太网1500),且IP头中DF(不分片)标志未设置,则IP层会进行分片 。但现在通常启用路径MTU发现,TCP主动调整MSS避免分片。

    • 设置协议字段为6,计算首部校验和,查路由表确定下一跳和出口接口。

    • 交给链路层。

  3. 数据链路层封装

    • 链路层(如以太网)根据ARP表获取下一跳MAC地址,添加14字节以太网帧头(目的MAC+源MAC+类型),尾部添加4字节FCS校验。

    • 如果网络层下发的IP包大于1500字节且不分片,则链路层无法发送,会丢弃并向网络层报告错误(需要MTU发现机制)。

  4. 物理层发送

    • 网卡将帧转换为串行比特流,加上物理层编码(如曼彻斯特编码),通过介质传出。

封装的关键点:每一层都认为自己在和对等层通信(逻辑通信),但实际上数据是垂直向下传递,经由物理介质到达对端后再垂直向上分用。

分用(Demultiplexing)详细过程(以服务器接收为例)

服务器网卡收到一串电信号后:

  1. 物理层与链路层

    • 网卡硬件识别前导码,同步时钟,将比特流还原成帧。

    • 检查目的MAC地址:若匹配本机MAC或为广播/组播地址,则接收;否则丢弃(混杂模式除外)。

    • 计算FCS并与帧尾对比,错误则丢弃帧。

    • 剥去帧头帧尾,根据"类型"字段(0x0800)将内层数据(IP数据报)提交给网络层的IP模块。

  2. 网络层分用

    • IP模块检查首部校验和、版本、总长度等。

    • 检查目的IP地址是否为本机地址之一(包括环回、广播)。若不匹配且未开启转发,则丢弃;若匹配则继续。

    • 查看"协议"字段:值为6,则将IP首部剥离,把内层数据(TCP段)提交给传输层的TCP模块。

    • 如果IP数据报是分片后的一个片段,则暂存于缓存,等待所有片段到齐后重组,再交给上层。

  3. 传输层分用

    • TCP模块收到TCP段,检查校验和。

    • 根据目的端口查找对应的Socket(即哪个进程在监听该端口)。如果是80端口,找到Web服务器进程的Socket。

    • TCP协议进行可靠性处理:检查序列号、发送确认ACK、重组乱序报文、放入接收缓冲区。

    • 当数据连续且完整时,TCP将数据拷贝到进程的用户空间(通过recv系统调用)。

  4. 应用层处理

    • Web服务器进程获得完整的HTTP请求报文,解析并生成响应,然后通过同一个Socket调用send将响应数据发回,开始新一轮的封装过程。

分用的精髓在于协议头部中的类型字段端口字段,它们起到了"拆包指引"的作用。


五、交互基本单元:请求与响应(再细化)

请求(Request)

以HTTP POST请求为例:

复制代码
POST /api/login HTTP/1.1
Host: www.example.com
Content-Type: application/json
Content-Length: 45

{"username":"alice","password":"123456"}
  • 请求行中的方法定义了操作语义:GET(获取)、POST(提交)、PUT(更新)、DELETE(删除)等。

  • 头部字段 Content-Length 至关重要,它告诉服务器本次请求正文的字节数。TCP是流式协议,没有边界,必须靠这个长度来区分后续字节流中哪部分是本次请求的正文,否则服务器可能无法正确读取。

  • 服务器处理完登录请求,可能返回一个包含Session ID的 Set-Cookie 头部,让后续请求携带凭证。

响应(Response)

对应响应可能如下:

text

复制代码
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 30

{"status":"success","token":"xyz"}
  • 状态码200 OK 表示成功。分类:1xx信息、2xx成功、3xx重定向、4xx客户端错误、5xx服务器错误。

  • 状态码 301(永久重定向)和 302(临时重定向)配合 Location 头部,告诉浏览器去新的URL获取资源。SEO优化中常用。


六、串起来:两台主机之间的网络通信完整流程

场景 :家庭电脑(Windows,IP 192.168.1.10,网关 192.168.1.1,浏览器Chrome)访问 Web 服务器(Linux,公网IP 93.184.216.34,监听80端口,网站 example.com)。

第一阶段:地址解析与连接建立

1. 应用层:URL解析与DNS查询
  • 用户在Chrome地址栏输入 http://www.example.com 回车。

  • 浏览器解析URL:协议 http,主机 www.example.com,端口默认 80

  • 浏览器检查自身DNS缓存?无。检查系统hosts文件?无。

  • 调用系统DNS解析函数(getaddrinfo),向配置的DNS服务器(如 8.8.8.8)发起UDP 53端口的DNS查询请求。

  • DNS请求的封装:应用层DNS报文 → UDP段(源端口随机,目的53) → IP数据报(目的IP 8.8.8.8) → 帧(目的MAC为网关 192.168.1.1)。

  • 经路由器转发后,DNS服务器返回响应,包含 www.example.com 的A记录:93.184.216.34

  • 浏览器获得目标IP。

2. 传输层:TCP三次握手
  • 浏览器调用系统Socket API,创建TCP套接字:socket(AF_INET, SOCK_STREAM, 0),连接目标:connect(fd, 93.184.216.34:80)

  • 操作系统内核协议栈开始三次握手(在内存中构建TCP状态控制块TCB):

    • 第一次握手 :内核生成初始序列号 Seq=client_isn(随机数,如 123456),SYN标志位置1,构造TCP段,下交IP层。IP层加头:源IP 192.168.1.10,目的IP 93.184.216.34,协议6。链路层查路由:目标IP非本网段,下一跳为默认网关 192.168.1.1,通过ARP获取网关MAC,构造帧发送。

    • 数据包经过家庭路由器(NAT转换:源IP变为公网IP,源端口变为路由器分配的新端口,记录NAT表),经互联网路由到达服务器。

    • 第二次握手 :服务器TCP模块收到SYN后,如果80端口处于LISTEN状态,则分配TCB,记录对方序列号,回复SYN+ACK段:Seq=server_isn(如 987654),Ack=123457

    • 数据包经互联网返回,路由器根据NAT表转换目的IP和端口,发给客户端。

    • 第三次握手 :客户端收到SYN+ACK,内核检查ACK号合法,回复ACK段:Seq=123457, Ack=987655,并通知应用层connect调用成功返回,连接进入ESTABLISHED状态。

3. 应用层:发送HTTP请求
  • 浏览器构造HTTP GET请求报文,调用 send(fd, request_data, ...)

  • 内核将数据拷贝到TCP发送缓冲区。TCP根据MSS和拥塞窗口,将数据分段,封装TCP头(源端口54321,目的端口80,Seq=123457,ACK标志置1,Ack=987655),交给IP层。

  • IP层封装,链路层封装,经物理网络发送。

第二阶段:服务器处理与响应

4. 服务器端接收与分用
  • 服务器网卡收到帧,按前述分用流程,最终将TCP段提交给监听80端口的Web服务器进程(例如Nginx的worker进程)。

  • Nginx从Socket中读取数据(read/recv),由于TCP是流,可能一次read读到了半个请求,或两个请求粘在一起。Nginx根据HTTP协议解析:寻找请求行结束符 \r\n,再读头部直到遇到空行,根据 Content-Length 读取指定长度的正文(GET请求通常没有正文)。

  • Nginx解析请求:方法GET,URI /,Host www.example.com

  • Nginx根据配置(如 root /var/www/html;),将URI映射到本地文件 /var/www/html/index.html

5. 服务器生成响应
  • Nginx检查文件是否存在,权限是否足够。若存在,通过 openread 系统调用读取文件内容(假设是一个简单的HTML文本)。

  • Nginx构造HTTP响应头:HTTP/1.1 200 OKContent-Type: text/htmlContent-Length: <文件大小>,以及其他头部(如 Connection: keep-alive)。

  • 调用 send 将响应头和文件内容数据写入Socket。内核TCP层将数据分段并发送。

第三阶段:响应返回与渲染

6. 响应路径上的封装与NAT
  • 服务器发出的IP数据报:源IP 93.184.216.34,目的IP为家庭路由器的公网IP(假设为 1.2.3.4),源端口80,目的端口为NAT映射后的端口(如 12345)。

  • 数据包经互联网路由,到达家庭路由器。

  • 路由器查NAT表:公网端口12345对应内网 192.168.1.10:54321。路由器修改目的IP为 192.168.1.10,目的端口为 54321,并重新计算IP校验和,转发到内网。

7. 客户端接收与渲染
  • 客户端内核收到响应帧,逐层分用,将TCP数据段放入Socket接收缓冲区,应用层 recv 返回HTTP响应数据。

  • 浏览器解析HTTP响应头,看到 Content-Type: text/html,开始解析HTML内容。

  • HTML中可能引用外部CSS、JS、图片资源。浏览器解析到 <img src="/logo.png"> 时,会再次发起新的HTTP请求(通常复用已有的TCP连接,如果 Connection: keep-alive),重复上述流程获取资源。

  • 浏览器完成渲染,呈现网页。

8. 连接关闭
  • 若HTTP头部包含 Connection: close,服务器发送完响应后会主动关闭连接(发送FIN)。

  • 客户端收到FIN后也发送FIN,经过四次挥手关闭TCP连接。

  • Connection: keep-alive,连接将保持一段时间,供后续请求复用,减少握手开销。


总结

概念 核心作用 在本次通信中的实际体现
IP地址 标识网络主机 客户端内网IP 192.168.1.10,服务器公网IP 93.184.216.34
端口号 标识主机进程 客户端临时端口 54321,服务器监听端口 80
协议 通信规则约定 HTTP定义请求响应格式,TCP保证可靠传输,IP负责寻址
协议分层 解耦复杂度 五层模型:应用层(HTTP) → 传输层(TCP) → 网络层(IP) → 链路层(以太网) → 物理层
封装 自上而下添加头部 HTTP报文 → TCP段(端口) → IP包(IP地址) → 以太网帧(MAC)
分用 自下而上剥离头部并分发 网卡收帧 → IP层根据协议号交TCP → TCP根据端口交Web服务器
客户端/服务器 主动请求方 / 被动响应方 Chrome浏览器(客户端)主动连接 Nginx(服务器)
请求/响应 一次通信的基本对话单元 GET / HTTP/1.1 → HTTP/1.1 200 OK + HTML 内容

扩展

步骤 典型耗时 原因
DNS解析 10~100ms 可能有多级递归,受DNS服务器远近影响
TCP握手 1个RTT(约20~200ms) 与服务器物理距离相关
发送请求 几十μs + 网络传输 取决于带宽和延迟
服务器处理 几ms ~ 几秒 取决于业务逻辑和数据库查询
响应传输 类似请求 受带宽和内容大小影响
浏览器渲染 几十ms ~ 数秒 JS/CSS解析执行,布局绘制

理解这些底层细节后,再去分析网络故障(如为什么连接超时?为什么网页打开慢?)便会游刃有余。网络世界虽复杂,但分层与封装分用的思想是贯穿始终的钥匙~~~以上就是本篇文章的全部内容啦~~咱们下篇再见~

相关推荐
路溪非溪2 小时前
Wireshark抓取以太网MAC帧并进行分析
linux·网络·驱动开发·wireshark
阿正的梦工坊2 小时前
JavaScript 函数组合(Compose & Pipe)详解
开发语言·javascript·网络
heimeiyingwang3 小时前
【架构实战】Docker容器网络模型详解
网络·docker·架构
深邃-3 小时前
【Web安全】-基础环境安装:虚拟机安装,JDK环境安装(1)
java·开发语言·计算机网络·安全·web安全·网络安全·安全架构
思麟呀3 小时前
UDP与TCP协议
网络协议·tcp/ip·udp
positive_zpc3 小时前
计算机网络——计算机网络和因特网
计算机网络
小江的记录本3 小时前
【网络安全】《网络安全与数据安全核心知识体系》(包括数据脱敏、数据加密、隐私合规、等保2.0)
java·网络·后端·python·算法·安全·web安全
@insist1233 小时前
网络工程师-动态路由协议(二):BGP 协议与路由引入技术详解
运维·网络·网络工程师·软考·软件水平考试
今天又在写代码3 小时前
计算机网络v2
网络·计算机网络