资讯动态

从 0 到 1 理解计算机网络:从网络基础到 Socket 编程

发布时间:2026/10/13 3:13:34 来源:尧图企业网站定制
个人主页道尔柯南❄专栏传送门《C语言》《C》《Linux操作系统》昙花一现却等待了整个白昼蝉鸣一夏却蛰伏了好几个四季。文章目录一、计算机网络为什么会出现二、网络通信首先要解决的问题大家必须“说同一种语言”协议Protocol三、协议为什么要分层四、OSI 七层模型理解网络的经典框架五、TCP/IP 五层模型1. 物理层2. 数据链路层3. 网络层4. 传输层5. 应用层六、真正理解网络数据到底是怎么发送出去的封装与解包七、不同层的数据为什么叫不同名字八、MAC 地址局域网中的“身份证”MAC 地址九、IP 地址解决“跨网络通信”IP 地址十、IP 地址和 MAC 地址到底有什么区别十一、数据到达主机还不够还要找到正确的进程端口号十二、端口号找到主机里的目标进程十三、从 IP Port 理解 SocketSocket十四、TCP 和 UDP两种不同的通信方式TCPUDP十五、网络字节序为什么网络数据必须统一格式网络字节序采用大端字节序十六、进入 Linux 网络编程Socket APIsocket()bind()listen()accept()connect()十七、一个最经典的 TCP 通信流程十八、sockaddrSocket API 如何表示地址十九、把整篇文章串起来一次网络通信究竟发生了什么二十、网络学习最重要的一张“地图”二十一、总结网络的本质是什么1. 为什么需要网络2. 为什么需要协议3. 为什么协议要分层4. MAC 地址解决什么问题5. IP 地址解决什么问题6. Port 解决什么问题7. Socket 是什么8. 网络通信的本质是什么写在最后结尾摘要计算机网络看似复杂但如果从“通信”这个最基本的问题出发就会发现网络中的许多概念其实都围绕着一件事情展开如何让不同主机上的不同进程可靠、准确地交换数据。本文从计算机网络的发展背景出发逐步理解网络协议、协议分层、OSI 与 TCP/IP 模型并进一步深入 MAC 地址、IP 地址、端口号、TCP/UDP、网络字节序以及 Socket 编程接口最终建立一套完整的计算机网络知识框架。一、计算机网络为什么会出现最初的计算机是一台一台独立工作的。可以简单理解成计算机 A 计算机 B 计算机 C ↓ ↓ ↓ 各自独立工作彼此之间没有直接的数据交换随着计算机数量越来越多人们很快发现一台计算机解决不了所有问题。计算机本质上是人的工具而人需要协同工作因此计算机之间进行数据共享和资源共享就成为必然需求。于是计算机从最初的独立模式逐渐发展到了网络互联。课件将这一过程概括为独立模式计算机之间相互独立网络互联多台计算机连接起来实现数据共享局域网 LAN通过交换机、路由器等设备连接更多计算机广域网 WAN进一步把相距很远的计算机连接起来。所以从本质上看计算机网络就是为了让不同计算机之间能够进行通信和资源共享。二、网络通信首先要解决的问题大家必须“说同一种语言”两台计算机连接起来之后是不是就可以直接通信了答案是不一定。假设计算机 A我用“频率”表示 0 和 1 计算机 B我用“电压强弱”表示 0 和 1即使两台计算机都在传输数据它们也无法正确理解对方。这就像两个人A你好我说中文。 BHello我说英语。两个人都在说话但由于缺少共同约定仍然无法正常交流。所以计算机之间通信需要一套共同遵守的规则。这就是协议Protocol课件对协议给出了一个非常朴素的理解“协议”是一种约定。进一步来看协议不仅仅是“约定语言”还需要规定数据应该是什么格式数据如何开始数据如何结束数据应该如何解释出错之后怎么办下一步应该交给谁处理。由于计算机厂商、操作系统、网络设备非常多因此必须存在一套大家共同遵守的标准才能让不同设备之间顺畅通信。三、协议为什么要分层如果把整个网络通信过程设计成一个巨大的协议会出现一个非常严重的问题太复杂了。例如一次网络通信可能同时涉及应用程序 ↓ 数据格式 ↓ 可靠传输 ↓ IP寻址 ↓ 局域网通信 ↓ 网卡 ↓ 网线 / Wi-Fi如果所有功能全部揉在一起那么任何一个地方发生变化都可能影响整个系统。因此协议也采用了软件工程中非常经典的思想模块化 解耦合课件指出协议本质上也是软件因此为了更好地进行模块化和解耦也被设计成层状结构。可以把它理解成┌──────────────┐ │ 应用层 │ ├──────────────┤ │ 传输层 │ ├──────────────┤ │ 网络层 │ ├──────────────┤ │ 数据链路层 │ ├──────────────┤ │ 物理层 │ └──────────────┘每一层只负责自己的事情并为上一层提供服务。这就是协议分层。四、OSI 七层模型理解网络的经典框架网络协议分层最经典的模型之一就是OSI 七层模型OSI即Open System Interconnection开放系统互连。它从逻辑上把网络通信划分成七层是一种理论上的参考模型。通常可以表示为7 应用层 6 表示层 5 会话层 4 传输层 3 网络层 2 数据链路层 1 物理层OSI 模型的优点非常明显概念清晰层次明确服务、接口和协议进行了区分有利于理解不同系统之间如何通信。但问题也很明显模型比较复杂在实际工程中并没有完全按照七层实现。因此实际学习和网络编程中我们更多使用 TCP/IP 模型。课件也明确指出OSI 七层模型虽然理论完整但复杂且不够实用因此后续按照 TCP/IP 模型进行讲解。五、TCP/IP 五层模型TCP/IP 是一组协议的统称它实际上包含大量不同协议共同组成 TCP/IP 协议簇。课件采用的五层模型为┌────────────────────┐ │ 应用层 │ ├────────────────────┤ │ 传输层 │ ├────────────────────┤ │ 网络层 │ ├────────────────────┤ │ 数据链路层 │ ├────────────────────┤ │ 物理层 │ └────────────────────┘下面逐层理解。1. 物理层物理层解决的是最底层的问题数据到底通过什么信号传输例如双绞线同轴电缆光纤Wi-Fi 电磁波。物理层决定了很多底层通信能力例如最大传输速率传输距离抗干扰能力。课件中还提到Hub集线器工作在物理层。2. 数据链路层数据链路层主要负责相邻设备之间的数据传输。它涉及数据帧网卡帧同步冲突检测数据差错校验MAC 地址。典型的设备是交换机 Switch课件明确指出交换机主要工作在数据链路层。3. 网络层网络层解决的是数据应该往哪里走这里最重要的概念就是IP 地址IP 地址用来标识网络中的主机同时网络层还需要进行路由选择。例如主机 A ↓ 路由器 1 ↓ 路由器 2 ↓ 主机 B这个过程中数据需要经过一个或多个路由器。典型的网络层设备就是路由器 Router4. 传输层传输层负责两台主机之间的数据传输。这里最重要的两个协议就是TCP UDPTCP 的特点面向连接可靠传输面向字节流。UDP 的特点无连接不可靠传输面向数据报。5. 应用层应用层离用户最近。例如浏览网页 发送邮件 文件传输 远程登录对应的应用层协议可以包括HTTPSMTPFTPTelnet。课件指出网络编程主要就是针对应用层。六、真正理解网络数据到底是怎么发送出去的到这里我们知道了很多概念应用层 传输层 网络层 数据链路层 物理层但是一个非常重要的问题出现了当程序发送一段数据时它究竟经历了什么答案就是封装与解包假设我们有这样一段应用数据Hello Linux数据从应用层向下传输。每经过一层该层协议都会增加自己的控制信息。可以简单理解为应用层 ┌──────────────┐ │ Hello Linux │ └──────────────┘ ↓ 传输层 ┌──────────┬──────────────┐ │ TCP头部 │ Hello Linux │ └──────────┴──────────────┘ ↓ 网络层 ┌──────────┬──────────┬──────────────┐ │ IP头部 │ TCP头部 │ Hello Linux │ └──────────┴──────────┴──────────────┘ ↓ 数据链路层 ┌──────────┬──────────┬──────────┬──────────────┐ │ MAC头部 │ IP头部 │ TCP头部 │ Hello Linux │ └──────────┴──────────┴──────────┴──────────────┘这个过程叫封装Encapsulation课件将报文概括为报文 报头 有效载荷。七、不同层的数据为什么叫不同名字网络数据在不同层有不同的名称。所处层次常见名称应用层数据传输层Segment / Datagram网络层Datagram数据链路层Frame例如应用数据 ↓ TCP Segment ↓ IP Datagram ↓ Ethernet Frame ↓ 物理介质到达目标主机之后过程反过来Frame ↓ 去掉链路层头部 ↓ Datagram ↓ 去掉网络层头部 ↓ Segment ↓ 去掉传输层头部 ↓ 应用数据这个过程就是解包 / 分用课件特别强调学习任何一个网络协议时都应该首先从宏观上考虑两个问题这个协议是如何解包的它如何把自己的有效载荷交给上层协议因为理解了解包也就更容易理解封包。八、MAC 地址局域网中的“身份证”如果两台计算机处于同一个局域网中它们如何知道数据到底发给谁这时候就需要MAC 地址MAC 地址用于识别数据链路层中相连的节点。课件中给出的特点是长度为 48 bit即 6 个字节通常使用十六进制表示常见格式类似08:00:27:03:fb:19在局域网通信过程中主机可以根据目标 MAC 地址判断这个数据是不是发给我的九、IP 地址解决“跨网络通信”MAC 地址解决了局域网中的设备识别问题。但是如果主机 A需要和另一个完全不同网络中的主机 B通信仅靠 MAC 地址就不够了。这时候就需要IP 地址IPv4 地址本质上是32 位整数通常使用点分十进制表示192.168.0.1每一个数字代表一个字节范围0 ~ 255十、IP 地址和 MAC 地址到底有什么区别这是网络学习过程中非常重要的一组概念。可以简单理解IP 是长期目标MAC 是下一跳目标。例如主机 A ↓ 路由器 R1 ↓ 路由器 R2 ↓ 主机 B整个过程中目的 IP ────────────────────────────→ 最终目标主机 B而 MAC 地址则随着一跳一跳的转发发生变化。课件对此进行了非常重要的总结IP 地址在路由过程中具有持续性的目标意义而 MAC 地址用于下一阶段的局域网转发。所以IP我要最终去哪里 MAC我这一跳应该交给谁十一、数据到达主机还不够还要找到正确的进程这里是网络学习中一个非常关键的转折。假设数据 → 目标主机是不是就结束了答案是不是。因为真正使用数据的是QQ 浏览器 迅雷 服务器程序这些实际上都是进程所以真正的通信目标不是主机而是主机上的某一个进程课件给出了一个非常重要的结论数据传输到主机不是目的而是手段到达主机内部再交给目标进程才是真正的目的。那么问题来了操作系统怎么知道应该把数据交给哪个进程答案端口号十二、端口号找到主机里的目标进程端口号属于传输层协议。它是一个16 bit的整数。端口号的作用就是标识主机上的网络进程。例如IP 192.168.1.100 Port 8080就可以表示192.168.1.100 这台主机上的某一个网络进程因此IP Port可以定位到某台主机上的某一个网络进程。十三、从 IP Port 理解 Socket到了这里我们已经有IP → 找到主机 Port → 找到进程所以IP Port就可以理解为一个网络通信端点。这就是Socket课件进一步将网络通信描述为两个进程之间的通信srcIP srcPort dstIP dstPort这四个信息共同描述通信双方。因此可以得到一个非常重要的结论网络通信的本质也是进程间通信。而IP Port可以理解为 Socket 的核心标识。十四、TCP 和 UDP两种不同的通信方式在传输层我们最常见的两个协议就是TCP UDPTCPTCP 的特点有连接 可靠传输 面向字节流可以理解为我不仅要把数据发出去还希望能够可靠地传递。UDPUDP 的特点无连接 不可靠传输 面向数据报可以理解为我更关注快速发送数据而不是建立复杂的可靠传输机制。需要注意的是这里只是对 TCP 和 UDP 建立一个初步认识真正理解它们还需要进一步学习 TCP 的连接管理、可靠性、流量控制、拥塞控制等机制。十五、网络字节序为什么网络数据必须统一格式在计算机中多字节数据存在大端 小端的问题。例如一个整数在不同 CPU 上可能采用不同的字节存储顺序。但是网络通信必须解决一个问题不同机器的数据表示方式可能不同怎么办TCP/IP 规定网络字节序采用大端字节序也就是说所有发送到网络上的数据都必须按照网络规定的字节序进行处理。因此在 Linux 网络编程中我们经常会看到htons()htonl()ntohs()ntohl()其中h host n network s short l long例如htonl()表示host to network long也就是将主机字节序的 32 位整数转换为网络字节序。十六、进入 Linux 网络编程Socket API当我们真正开始写网络程序时就会接触Socket API最基本的 Socket 接口包括socket()bind()listen()accept()connect()其中socket()创建 Socket。intsocket(intdomain,inttype,intprotocol);bind()将地址和端口绑定到 Socket。intbind(intsocket,conststructsockaddr*address,socklen_taddress_len);通常服务器需要执行。listen()让 TCP 服务器进入监听状态。intlisten(intsocket,intbacklog);accept()接收客户端连接。intaccept(intsocket,structsockaddr*address,socklen_t*address_len);connect()客户端主动连接服务器。intconnect(intsockfd,conststructsockaddr*addr,socklen_taddrlen);这些 API 是 Linux Socket 网络编程的基础。十七、一个最经典的 TCP 通信流程把前面的知识串起来一个 TCP 服务器大致可以理解为服务器 socket() ↓ bind() ↓ listen() ↓ accept() ↓ read / write ↓ close()客户端socket() ↓ connect() ↓ read / write ↓ close()可以画成TCP服务器 TCP客户端 socket() socket() ↓ ↓ bind() connect() ↓ ↓ listen() ───────────────→ 建立连接 ↓ accept() ↓ 数据读写 ←──────────────→ 数据读写 ↓ close() close()这样一来我们就把前面学习的应用层 ↓ 传输层 ↓ 网络层 ↓ 数据链路层 ↓ 物理层与 Linux 中实际可以调用的socket() bind() listen() accept() connect()联系起来了。十八、sockaddrSocket API 如何表示地址Socket API 是一套比较通用的网络编程接口。不同协议的地址结构可能不同因此 Linux 使用structsockaddr作为通用接口。而在 IPv4 网络编程中我们真正经常使用的是structsockaddr_in它主要包含地址类型 端口号 IP地址课件指出IPv4 地址使用sockaddr_in表示而sockaddr_in中包含地址类型、16 位端口号和 32 位 IP 地址。所以可以简单理解sockaddr ↓ 通用地址接口 sockaddr_in ↓ IPv4 地址结构十九、把整篇文章串起来一次网络通信究竟发生了什么现在我们可以把整个过程完整地串起来。假设浏览器访问一个服务器。首先浏览器是一个进程。它需要把数据发送出去。↓通过Socket进入操作系统网络协议栈。↓传输层TCP / UDP负责主机之间的数据传输。↓网络层IP负责寻找目标主机以及进行路由。↓数据链路层MAC负责当前局域网中的数据传输。↓物理层网线 / 光纤 / Wi-Fi最终把数据转换成信号发送出去。完整过程可以抽象成应用程序 │ ▼ Socket API │ ▼ ┌─────────┐ │ 应用层 │ ├─────────┤ │ 传输层 │ ← TCP / UDP / Port ├─────────┤ │ 网络层 │ ← IP / Routing ├─────────┤ │链路层 │ ← MAC / Frame ├─────────┤ │ 物理层 │ ← 网线/Wi-Fi/光纤 └─────────┘ │ ▼ 网络 │ ▼ 目标主机 │ ▼ 目标进程这就是整个网络通信的宏观视角。二十、网络学习最重要的一张“地图”如果刚开始学习 Linux 网络编程很容易被大量概念弄得混乱。其实只需要抓住下面这张关系图网络通信 │ ┌─────────┴─────────┐ │ │ 主机之间 进程之间 │ │ IP Port │ │ └───────┬───────────┘ │ Socket │ TCP / UDP │ 网络协议栈 │ ┌────────────┼────────────┐ │ │ │ 应用层 传输层 网络层 │ IP │ 数据链路层 │ MAC │ 物理层理解这张图之后后续学习TCP UDP HTTP DNS Socket 路由 交换机 网络编程都会容易很多。二十一、总结网络的本质是什么学习完这一部分我们可以用几个问题来总结整个网络体系。1. 为什么需要网络因为不同计算机之间需要通信和共享数据。2. 为什么需要协议因为不同计算机之间必须遵守共同的通信规则。3. 为什么协议要分层因为分层能够模块化、解耦合降低系统复杂度。4. MAC 地址解决什么问题解决局域网内设备的识别与转发问题。5. IP 地址解决什么问题解决跨网络的主机寻址和路由问题。6. Port 解决什么问题解决一台主机内部不同网络进程的识别问题。7. Socket 是什么可以从网络编程的角度理解为网络通信端点。8. 网络通信的本质是什么最终可以归纳为不同主机上的不同进程之间进行数据交换。写在最后计算机网络刚开始学习时看起来会充满各种陌生概念MAC IP TCP UDP Port Socket Frame Segment Datagram Router Switch但如果把这些概念拆开来看它们其实并不是孤立存在的。它们共同解决的是一个问题如何让一个主机上的进程把数据准确地交给另一台主机上的目标进程。因此可以把整个网络通信过程浓缩成一句话进程 ↓ Socket ↓ Port ↓ TCP/UDP ↓ IP ↓ MAC ↓ 物理介质 ↓ 网络 ↓ 目标主机 ↓ 目标Port ↓ 目标进程这条链路就是理解 Linux 网络编程最重要的主线。当这条主线真正建立起来之后后面再学习TCP 三次握手、四次挥手、UDP、HTTP、DNS、路由、NAT、网络抓包以及 Linux Socket 编程就不再是一个个孤立的知识点而是在不断填充这张网络知识地图。而这也正是从“会使用网络”走向“真正理解网络”的开始。结尾uu们本文的内容到这里就全部结束了道尔在这里再次感谢您的阅读道尔柯南C/C Linux 底层探索者 | 一个正在努力学习的技术博主【关注】跟随我一起深耕技术领域见证每一次成长。❤️【点赞】让优质内容被更多人看见让知识传递更有力量。⭐【收藏】把核心知识点存好在需要时随时查、随时用。【评论】分享你的经验或疑问评论区一起交流避坑不要忘记给博主“一键四连”哦“今日目标达成”结语希望对学习Linux相关内容的uu有所帮助不要忘记给博主“一键四连”哦

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑