网络通讯基础入门:从输入网址到数据包传输的完整链路解析
1. 从敲下网址开始计算机是怎么找到对方的很多朋友刚开始接触网络通讯第一反应就是去背各种协议的名字什么TCP、UDP、HTTP、DNS背完就忘因为不知道这些东西到底解决什么问题。我个人的经验是想搞懂网络通讯别从协议定义出发从一个最简单的动作出发你在浏览器地址栏敲下一个网址按下回车页面出来了。这个过程里你的电脑到底做了哪些事中间经过了哪些设备那些基础概念分别扮演什么角色把这根链条捋顺了后面看什么协议都轻松。先说最底层的一个概念MAC地址。你可以把它理解成网卡的身份证每一块网卡出厂的时候都会烧录一个全球唯一的物理地址这个地址是硬件层面的不跟你所在的位置发生任何关系。你的电脑、手机、路由器凡是能联网的设备至少都有一块网卡也就都有一个MAC地址。为什么先说它因为两个设备之间要通信最基础的前提是相互能找到而MAC地址就是局域网上邻居之间互相识别的依据。但光是MAC地址还不够你想想你自己的电脑肯定不止接入过一台路由器你在家里连着路由器A到了公司又连着路由器B路由器B和路由器A完全没有关系。如果全世界都只靠MAC地址寻址那就相当于每家快递公司都按收件人的姓名找人同名同姓的问题根本没法解决。所以网络通讯里还有第二个更重要的标识IP地址。IP地址解决的是“你在哪个网络、该怎么找到你”的问题可以理解为门牌号而且这个门牌号是可以变化的。你家的宽带换了运营商IP地址可能就变了你手机从家里出来切到流量IP地址也会变。一个设备在网络里的身份靠的就是“硬件身份证MAC 当前门牌号IP”这一对组合。这里有个非常容易混淆的点既然有了IP地址为什么还要MAC地址我常用一个类比IP地址是城市、街道和门牌号MAC地址是收件人本人。数据包从一个网络传到另一个网络中间经过很多路由器每台路由器都只负责把数据往“下一跳”送这个“下一跳”的范围内真正认人的还是MAC地址。换句话说IP地址负责跨网络定位MAC地址负责局域网内的最终投递。两者各司其职缺一不可。在初学阶段你不需要把MAC地址的原理背得多深但至少要做到知道自己怎么看电脑的MAC地址和IP地址。Windows系统里打开命令行输入ipconfig /all能看到网卡对应的MAC地址和IPv4地址macOS或Linux里用ifconfig或ip addr。这些命令我后面讲排查问题时还会提到属于基础中的基础。有了地址之后你的电脑和数据要找到对方还需要一个关键的“翻译”过程这就引出了DNS。我单独拎出来讲因为新手在这里特别容易产生焦虑感明明我访问的是百度为什么电脑要先去找一个叫“域名服务器”的东西2. 找人的方式与寻路规则DNS、端口和传输链路2.1 DNS到底在做什么把人类语言翻译成机器语言你在浏览器里输入的这个网址本质上是一个“域名”比如example.com这东西是给人看的好记。但网络底层的寻址系统只认IP地址不认域名。所以你的电脑在发起任何网络请求之前必须先问一台专门的服务器这个域名对应的IP地址是多少这台服务器就是DNS服务器。DNS的工作原理可以简化成一句话它是一本巨大的、分布式的通讯录。你的电脑把“example.com”这个域名交上去DNS服务器查一下自己的缓存和记录返回一个IP地址比如93.184.216.34然后你的电脑才真正向这个IP发起连接请求。这个过程在正常网络环境下是毫秒级的你完全感知不到但它就是事实上的“第一步”。我遇到过不少新手问为什么我感觉DNS挺快的这是因为DNS有缓存机制。你的电脑、路由器、运营商都有DNS缓存当有人问过同一个域名之后后续的查询就不需要每次都去根服务器逐个问。当然这也带来了一个排查体验上的坑万一DNS缓存里的记录已经过期了而你访问的网站换了服务器IP你可能就会遇到“明明别人能打开就我打不开”的情况。这时候最简单的解决办法就是刷新本地DNS缓存Windows下执行ipconfig /flushdnsmacOS下执行sudo dscacheutil -flushcache。这个动作我后面还会提到先写在这里。这里还可以顺手补一个概念DNS不仅能把域名翻译成IP还能做反向的事把IP翻译回域名不过日常用得少初学阶段知道人名和电话本的关系就够了。你只需要记得DNS用的是UDP协议的53号端口做主查询这句话等你看到下一章端口和协议之后就能完全理解了。2.2 端口同一台机器上凭什么区分不同服务现在你的电脑已经拿到了目标服务器的IP地址接下来要发起连接。但有个问题一台服务器上往往同时跑着很多服务网页服务、邮件服务、文件传输服务都在这台机器上。数据包冲着这个IP来了服务器怎么知道它是来访问网页还是来收邮件的答案就是端口。端口可以理解成门牌号后面的“房间号”。IP地址确定了是哪一台机器端口确定了是该机器上的哪一个服务。默认情况下网页服务走80端口加密的网页服务走443端口邮件走25或587端口DNS走53端口。这些是约定俗成的“常用默认端口”你在配置服务的时候如果不改它们就会监听在这些端口上。新手往往会把端口理解成物理存在的某个接口其实不是。端口是软件层面的逻辑概念由传输层协议在数据包头里用16位数字标记出来范围从0到65535。其中0到1023是公认端口一般给系统服务用1024到49151是注册端口给应用软件用49152到65535是动态端口通常作为客户端发起连接时临时分配的源端口。我之所以把这个概念放到寻路这章来讲是因为端口在一个完整的通讯过程中扮演的角色特别容易被人忽略。你发起网页访问时本地会随机挑一个高位端口作为源端口目标服务器的80或443端口作为目的端口。对方回包时源端口和目的端口会对调。也就是说通讯双方其实是靠“IP地址 端口 传输层协议”这个组合来识别一条连接的。这四个要素缺一个都没法准确描述一条网络连接。2.3 数据包是怎么被转发的交换机、路由器与NAT理解了地址和端口接下来就该说链路了。你的电脑把数据封装好之后数据要从你的网线或Wi-Fi出发先到家里的路由器然后穿过运营商网络经过一道道转发最终到达目标服务器。这个过程中局域网内和跨网络转发靠的是两种不同的设备交换机负责局域网内基于MAC地址的转发路由器负责跨网络基于IP地址的转发。这里有一个很经典的理解误区很多人认为路由器主要功能是发Wi-Fi信号其实Wi-Fi只是路由器顺带附带的接入功能它真正的本职工作是路由和转发。家里那种长得像盒子的设备严格来说应该叫“宽带路由器”它把家里所有的设备组成一个局域网同时通过PPPoE拨号等方式接入运营商的网络。内网的设备如果要访问外网流量会统一交给这台路由器来处理。路由器里还有一个对家庭网络特别重要的机制NAT网络地址转换。因为IPv4地址资源太紧张了家里所有设备不可能每台都有一个公网IP于是路由器把所有内网设备的IP统一“翻译”成一个公网IP再发出去。回包到达路由器后路由器再根据之前的映射记录把数据转发回对应的内网设备。这个机制就是为什么你家这么多设备上网运营商只分配了一个公网IP的原因。由于NAT的存在你会遇到一个很常见的情况你想从外部访问家里的一台设备如果没有在路由器上配置端口映射流量根本进不去。因为外部数据包到达路由器的公网IP后路由器不知道该转发给内网的哪一台机器。想通这一点你就理解了为什么很多人折腾远程访问、NAS、摄像头监控时总要在路由器后台做端口转发或者开UPnP。这不是设备坏了是NAT在“挡路”。讲到这前两层的基础概念算是串起来了MAC地址做局域网的接力IP地址做跨网络的定位DNS把域名翻译成IP端口区分同一台机器上的不同服务NAT让内网设备可以用一个公网IP出去。接下来要进入整个网络通讯里最核心、也最容易被新手绕晕的部分传输层。3. 传输层的两个主角TCP与UDP的分工3.1 为什么数据不能“裸奔”发送你可以把网络通讯看成寄包裹。前面说的IP协议只负责把包裹从源地址送到目的地址但它不管包裹有没有在中途损坏、丢失也不管到达的顺序对不对。对很多应用来说这绝对不能接受。比如你在传一个文件中途丢了一个包文件就坏了你在看网页内容顺序乱了页面就没法显示。所以IP上面还需要一层机制来保证传输的可靠性这层机制就是传输层。传输层有两个最常见的协议TCP传输控制协议和UDP用户数据报协议。一个可靠但相对慢一个不可靠但飞快。为什么要同时存在两种因为不同的应用有不同的需求全部统一用可靠的TCP视频通话和在线游戏就受不了那个延迟全部用不可靠的UDP网页和文件传输就没法用。所以网络设计者没有搞一刀切而是给应用提供了两种模式。初学阶段不需要研究协议头部的每一个二进制位但要抓住TCP和UDP的本质区别TCP是面向连接的、可靠的、字节流的协议UDP是无连接的、不可靠的、数据报的协议。这句话背下来没用你得理解它背后意味着什么。连接是什么可靠性又是靠什么换来的我下面拆开讲。3.2 TCP三次握手为什么一定要确认三次TCP最重要的特点是“面向连接”。什么叫连接不是物理上拉了一根线而是通讯双方在正式传数据之前先交换几轮消息确认“你准备好了我也准备好了可以开始传了”。这个过程就是经典的TCP三次握手。具体流程是客户端先发一个SYN报文意思是“我想跟你建立连接”服务器收到后回复SYNACK意思是“我收到了我也准备好跟你建立连接”客户端再回一个ACK意思是“我收到你的确认了那咱们开始传数据吧”。三次之后连接正式建立才开始传输真正的业务数据。为什么要三次而不是两次这是为了让双方都确认自己和对方的收发能力是正常的。你想想如果只有两次握手客户端发出SYN服务器回了个ACK就算建立连接服务器此时并不知道客户端有没有收到自己的ACK。万一客户端没收到呢连接就处于一种“一个以为建立了另一个以为没建立”的诡异状态。三次握手能保证双方都确认了“我能发、我能收、能收到对方的确认”这个三角关系闭合了才敢开始传数据。很多朋友问我怎么直观理解三次握手我总是让他们抓一次包看看。这个放到第5章实操里讲但先记住结论任何基于TCP的应用比如HTTP网页访问正式通讯前都有这个三次握手过程。你在用浏览器打开一个网页时实际发生的TCP握手其实不止一次因为页面里的图片、脚本会各自建立连接不过现在有了HTTP/2和连接复用机制情况比以前好很多。这里不展开知道有大坑在后面就没问题。3.3 TCP的可靠性机制确认、重传、排序三次握手只是TCP可靠性的开头数据真正传输过程中还有一整套保障机制。TCP把要发送的数据拆成一个一个的报文段每个报文段都有编号接收方收到一个编号的报文段后会回一个确认ACK告诉发送方“我收到了”。假如发送方超时没收到确认就认为这个报文段丢了于是重传一份。这就是TCP最基本的可靠传输机制。但TCP的可靠并不是一次一个确认那么死板那样效率太低了。实际使用的是滑动窗口机制发送方可以一次发一批数据接收方批量确认窗口的大小还可以动态调整这叫流量控制。如果网络拥堵了TCP还会自动降低发送速率让数据不以过快的速度去加重拥塞这是TCP的拥塞控制机制。这一整套组合拳才是TCP“可靠”二字的完整含义。新手不需要会算拥塞窗口的系数但需要建立一种直觉TCP的所有可靠性都是拿延迟和带宽换来的。确认要花时间重传要花时间流量控制让发送端不能拼命发。所以只要应用追求的是“绝对正确的数据”就适合用TCP只要应用追求“快”并且能容忍部分数据丢失就适合用UDP。这种取舍思维比记住协议细节重要得多。3.4 UDP为什么视频通话和游戏反而偏爱它UDP和TCP最大的区别就是它不建立连接不管送达也不管顺序。它就像发一封平信邮局投递了就不管了收不收得到全看运气。你要问这有什么用天大的用处。举个最直观的例子视频通话。视频画面一秒钟有几十帧如果这一帧丢了下一帧马上就来你根本注意不到如果为了等一个丢失的帧整个画面停滞下来反而谁都受不了。语音也是你网络抖了一下某几个字的音频数据丢了听起来只是有一点点卡但整体对话毫不受影响。这些场景下UDP的低延迟、无连接的开销优势就完全体现出来了。游戏也是同理尤其是动作类和射击类游戏玩家操作要尽可能快地同步到服务器和其他玩家那里。如果用TCP一旦某个包重传后面的操作都得排队等着你按了键画面半天没反应那是灾难级别的体验。所以我们经常听到的“用UDP做游戏同步”本质上是在效率与可靠性之间做了取舍宁可丢帧也不要卡顿。不过现代实际应用中趋势是两层融合很多应用在UDP之上自己再实现一套“轻量可靠”机制只对最关键的控制消息做确认和重传对海量的音视频数据则完全放养。比如很多实时通讯框架、音视频SDK都是这种思路。学TCP和UDP的时候不要把它们看成一刀切而是看成一条“可靠性与效率”的光谱实际工程中你可以在光谱上自由选择这才是传输层设计的精髓。4. 应用层协议HTTP/HTTPS、DNS与DHCP4.1 HTTP的请求-响应模型传输层把数据可靠地送过去之后接下来要解决的才是“你打开网页”这个最终需求。HTTP协议跑在TCP之上它规定了浏览器和服务器讲话的格式。浏览器发一个请求Request服务器回一个响应Response一来一回一个事务就完成了。这个模型就是整个万维网的基础。HTTP请求由三部分组成请求行包含方法、路径、协议版本、请求头包含Host、User-Agent、Cookie等元信息、请求体包含POST提交的数据等。服务器返回的响应也类似状态行里有一个状态码比如200表示成功404表示找不到资源500表示服务器内部错误然后是响应头和响应体。初学基础概念时至少要做到见到状态码能认出大类2xx是成功3xx是重定向4xx是客户端的锅5xx是服务器的锅。有个概念必须一开始就拎清HTTP和HTTPS是两回事。HTTPS是在HTTP外面套了一层TLS/SSL加密。为什么需要它因为HTTP的报文是明文传输的中间的任何一台路由器、任何一个节点都能看到你的请求内容包括密码、聊天信息、支付信息全部裸奔。TLS层做的事情是加密传输内容、校验数据完整性、验证服务器身份。现在的网站基本全站启用HTTPS有些浏览器甚至直接把HTTP页面标记为不安全这已经是大势所趋。初学网络通讯一上来就扎进HTTP的报文细节不太划算容易陷入“知道每行头字段含义”但不知道它们之间如何协作的局面。更好的做法是把它当成你理解TCP报文的一个应用场景浏览器建立TCP连接发送HTTP报文服务器回HTTP响应浏览器解析渲染。等到你熟练了之后再去抠Cache-Control、ETag、Cookie这些头字段会事半功倍。4.2 DHCP你的手机是怎么在接入网络时自动拿到IP的前面讲了IP地址却没讲它从哪来。你可能觉得手机连上Wi-Fi就能上网“IP地址”这个概念仿佛没有存在感。实际上这个过程是DHCP协议在暗中帮忙。DHCP动态主机配置协议允许设备接入网络后自动向DHCP服务器申请IP地址、子网掩码、默认网关、DNS服务器地址等参数。DHCP的工作过程简单来说就是四个步骤发现、提供、请求、确认。设备先在局域网内广播一个“有没有DHCP服务器能给我分配IP呀”局域网内的DHCP服务器通常就是家里的路由器收到后回复“我这个地址池里有IP给你留了一个”设备再确认“我就用这个地址了”服务器答复“好的确认给你使用租约多久多久”。整个过程是自动完成的所以你手机上“IP地址”那栏永远是自动填好的。虽然DHCP是自动的但排查网络问题时它经常成为坑点来源如果你把某个设备的IP设为“静态”但静态地址和DHCP自动分配的地址冲突了就会出现“一会儿能上网一会儿不能上”的灵异现象。所以新手做实验时如果改过手动IP一定记得改回“自动获取”。另外一个跟DHCP相关的常见操作是DHCP租约续约Windows上经常用ipconfig /release和ipconfig /renew强制让网卡释放并重新申请IP用于解决“接入某个新网络但拿不到正确IP”的问题。4.3 分层思维为什么每条协议都只管自己那一段学到现在你已经接触了IP、TCP、UDP、HTTP、DNS、DHCP光协议名就够记一阵了。如果把它们都混在一起理解很容易乱。网络通讯能运转起来一个重要设计思想是分层。每一层只解决某一类问题层与层之间通过标准接口沟通上一层的请求交给下一层来“服务”下一层的细节对上一层完全透明。有个特别好的生活化类比你点外卖。你只管在一家外卖平台上选好餐、下单这个动作相当于应用层的HTTP请求外卖平台把订单派给商家商家做餐相当于服务器处理请求骑手取餐、送餐中间可能经过多个站点转运这类似传输层和网络层的数据搬运你收到外卖打开一看跟平台页面上展示的图片一致这相当于各个层校验了数据的完整性让你应用层拿到的结果“符合预期”。整个过程中你完全不需要关心骑手走的哪条路、商家和平台之间用了几台服务器这个“不用关心细节”的能力就是分层带来的好处。所以当你看到“TCP/IP四层模型”或“OSI七层模型”时别把它们当死记硬背的考题它们是帮助你定位问题的一个坐标系。网络不通了工程师先判断是哪层的问题物理层网线没插好数据链路层的VLAN配错了网络层的IP路由不对传输层的防火墙禁了端口应用层的程序报错了层次理清楚排查网络问题的思路自然就清晰了这是后续一切实操的基础。5. 实操侧记用抓包工具把概念落地5.1 用ping和tracert检查基础连通性概念讲再多不落地总是虚的。我建议每个初学者都做一遍下面这套实验十分钟就能把之前提到的概念全部串起来。第一个命令是ping。ping用ICMP协议向目标主机发探测报文对方回应一个回显报文就能马上判断“通往对方的网络通不通”。实际使用时作用有两个一是确认本机网络栈是否正常二是确认到达某个远端主机是否可达。我会先ping 127.0.0.1这是回环地址如果通说明本机网络协议栈没问题接着ping 网关IP如果通说明局域网内部没问题再ping 一个公网IP比如223.5.5.5如果通说明外网链路也没问题。这套“由近及远”的排查顺序是我处理网络问题时的标准起手式。第二个命令是tracertWindows叫tracertmacOS/Linux叫traceroute。它能看到数据包从你的电脑出发经过哪些路由器节点到达目的地。怎么实现的它发送一系列TTL生存时间值递增的报文TTL每经过一台路由器就减1减到0路由器就回一个超时错误于是你能依次看到每一跳的路由器IP和时延。这个命令非常直观地展示了“跨网络寻路”的过程比任何示意图都管用。5.2 用抓包工具观察TCP三次握手如果说ping和tracert是听觉测试那抓包就是直接让你“看到”数据长什么样。抓包工具里最常用的开源方案是Wireshark图形界面配合tcpdump命令行初学者建议直接从Wireshark入手。怎么抓一次HTTP的三次握手在Wireshark里选好你的上网网卡设置一个过滤器tcp port 80 or tcp port 443然后打开浏览器访问任意站点回到Wireshark里停止。你会在列表里看到一系列TCP报文找到最开始那几条SYN、SYNACK、ACK那就是三次握手。选中某一条报文在下方详情面板里展开“TCP”层级能看到源端口、目的端口、序列号、确认号、窗口大小等所有字段。你在第3章里背过的抽象概念在那一刻会变得无比具体。这个实验还有一个进阶玩法过滤HTTP请求观察明文协议。访问一个HTTP站点注意是HTTP不是HTTPS过滤http你会看到请求行、请求头、响应状态等结构。而如果访问的是HTTPS站点过滤tls看到的则是一堆加密后的密文除了握手阶段的几个证书交互可以解析业务数据几乎全部不可读。这一前一后的对比比任何解释都让你懂得为什么网页要上HTTPS。5.3 一个经典案例网页能打开但下载很慢前面讲了很多正常情况下的流程现在讲个实际排查中常遇的案例帮助你理解TCP可靠性机制如何在真实世界中起作用。现象是网页能打开图片也显示但下载大文件时速度上不去时快时慢。排查第一步看是不是UDP或TCP被限速。我们用iperf3或者干脆看一下当前TCP连接的实时窗口。实际上对初学者来说更直接的是看Wireshark里的TCP报文有没有大量重传。如果有TCP重传说明存在丢包而丢包就意味着TCP要重传重传就要等待超时窗口这中间白白浪费了大量时间。导致丢包的原因可能是链路质量差、Wi-Fi信号弱、路由器负载高、或者广域网出口拥堵。当你能理解“丢包——重传等待——速度下降”这个因果关系后很多网络慢的问题都能归到根因上。比如你换个信道、换根网线、换台路由器问题可能就解决了。这就是为什么我一直强调不要死记TCP的拥塞控制算法叫什么名字用抓包工具看到重传标记那一刻你就彻底明白为什么TCP在差链路上会这么慢了。理论联系实际比任何公式都刻骨铭心。6. 新手踩坑精选与快速自查清单6.1 我见过最多的四个常见问题第一把IP地址和MAC地址混为一谈。很多朋友问我我改一下电脑的MAC地址是不是就等于换了台新电脑严格来说改MAC只是让局域网内的设备认不出你原来的网卡但无法改变你设备本身。真正定位你当前位置的还是IP。这两个地址各管一摊别互相替代。第二用ping的结果来判断“网站是否正常”。ping通只代表一个主机IP能回应ICMP不代表它的HTTP服务正常。我见过不少人说“我ping通官网了为什么网页打不开”因为很多网站的服务器对ICMP做了限制或404页面仍然会回应TCP连接但应用层就是出错了。判断网页服务是否正常工作应该用浏览器、curl或者刷新一遍HTTPS请求而不是只依靠ping。第三以为改了DNS服务器设置就能解决所有上网慢的问题。DNS只影响域名解析阶段的速度和准确性一旦域名解析完成后续的流量跟DNS再没关系。如果你的网络本来就带宽不够、延迟很高换再快的DNS服务器都救不了。合理的做法是先ping 域名看看域名解析出来的IP对不对再tracert看看链路延迟和丢包情况分层定位。第四忽略局域网内IP地址冲突。这个问题特别容易在路由器开启DHCP而你又手动设置了静态IP时发生。两个设备用了同一个IP数据包到了路由器后不知道该发给谁就会表现出间歇性断网。排查手段很简单把所有设备恢复为自动获取IP同一个局域网内就不会再出现IP冲突。6.2 一个实用的快速自查顺序有了前面的基础我把自己常用的排查顺序整理成一个清单你以后遇到网络问题可以直接照着做看网卡状态。网线灯亮吗Wi-Fi信号有没有丢这一步排掉物理层的问题。ping 127.0.0.1确认本机网络协议栈是否正常。ping 网关IP确认局域网链路是否正常。ping 公网IP确认外网链路是否通。ping 域名确认DNS解析是否正常。浏览器访问站点如果打不开再看状态码是4xx还是5xx定位是客户端问题还是服务端问题。如果时通时断抓包看TCP重传分析链路丢包。这个顺序的好处是每一步都有一个明确的结论从底层往高层一层层排除绝对不会两头瞎猜。每次做完这个序列基本都能把问题范围缩到很小的范围内。你会在反复使用中发现所谓“会排查网络”其实就是熟练地运用分层思维在正确的层面上寻找证据。6.3 最后分享一点自己的习惯作为一个常年跟网络打交道的人我最后再说一个经验学网络通讯基础概念千万别急着一次性把所有协议都搞明白一次就学一张图、一个场景。今天搞懂DNS明天搞懂TCP握手后天搞懂一次完整的网页请求流程。信息量不大但每个知识都扎扎实实。我见过太多朋友买了一堆大部头教材翻开第一页是全协议栈的缩写表瞬间就劝退了。网络通讯是一个体系但每个知识点都可以单独消化没有必要一次吃完。你只要先抓住“谁找谁用什么找怎么送怎么保证送到”这条主线后面不管遇到什么协议都能把它安到这条主线上合适的位置。