前言:
- IP地址:标识唯一主机
- 端口号:表述主机上的唯一进程
- socket套接字(IP + 协议 + 端口):应用层与 TCP/IP 协议栈传输层(内核实现)交互的中间桥梁
- TCP、UDP协议概念
- 网络字节序(大端字节序)及其接口
目录
- [1. 网络通信的本质(IP地址标识唯一主机)](#1. 网络通信的本质(IP地址标识唯一主机))
- [2. 认识端口号(端口号标识唯一进程)](#2. 认识端口号(端口号标识唯一进程))
-
- [2.1 端口号概念](#2.1 端口号概念)
- [2.2 理解 "端口号" 和 "进程ID"](#2.2 理解 "端口号" 和 "进程ID")
- [2.3 理解源端口号和目的端口号](#2.3 理解源端口号和目的端口号)
- [3. 理解socket(套接字)](#3. 理解socket(套接字))
- [4. 传输层的典型代表](#4. 传输层的典型代表)
-
- [4.1 认识 UDP 协议](#4.1 认识 UDP 协议)
- [4.2 认识 TCP 协议](#4.2 认识 TCP 协议)
- [5. 网络字节序(大端字节序)](#5. 网络字节序(大端字节序))
1. 网络通信的本质(IP地址标识唯一主机)
- IP地址 在网络中,用来标识主机的唯一性。(注意:后面我们会讲 IP 的分类,后续也会详细阐述 IP 的特点。)
在这里,我们可以先思考一个核心问题:数据传输到目标主机就是最终目的吗?答案是否定的。因为数据最终是给人使用的,比如聊天、下载文件、浏览网页这些行为,本质上都是人在操作。
但人并不能直接接收和处理网络数据,而是通过启动对应的应用程序来完成 ------ 比如 QQ、迅雷、浏览器,而这些启动后的应用程序,在操作系统中对应的就是进程 。换句话说,++进程是人在系统中的代表++,只要把数据准确交付给对应的进程,人就相当于拿到了数据并完成相应操作。
所以,我们可以得出一个重要结论:数据传输到主机不是目的,而是手段;到达主机内部后,再将数据交付给主机内的目标进程,才是网络通信的最终目的。
我们日常上网主要包含两种核心行为:
- 从远端服务器获取数据(如下载文件、浏览网页、接收聊天消息);
- 从本地将数据上传到远端服务器(如发送聊天消息、上传文件、提交表单)。
这两种行为的底层数据流转路径均为以下两种:
进程(内存) → 网卡 → 网络 (发送端)
网络 → 网卡 → 进程(内存)(接收端)。
结合以上内容,我们可以提炼出网络通信的本质:网络通信并非两台主机之间的直接交互,而是两个不同主机上的进程在进行跨主机数据交互,本质上属于一种特殊的进程间通信。
我们知道,普通的进程间通信是让同一主机内的不同进程看到同一份资源,而网络通信(跨主机进程间通信)的核心,就是让不同主机上的进程看到同一份网络资源(如传输的报文数据)。
但这里又引申出一个关键问题:操作系统中同时会存在大量进程,当数据到达目标主机之后,如何精准转发给对应的目标进程?这就需要在 "IP 标识主机唯一性 " 的基础上,进一步找到能在网络背景下、系统内标识进程唯一性 的方式 - 端口号

总结:
IP地址:用来定位在庞大的网络中的某一台指定的主机。
端口号:用来定位主机内的网络通信进程
2. 认识端口号(端口号标识唯一进程)
2.1 端口号概念
端口号(port)是TCP/IP 传输层协议(TCP/UDP)的核心内容,用于解决目标主机内进程的精准寻址问题。
- 端口号是一个 2 字节(16 位)的无符号整数,取值范围为 0 - 65535,按用途可分为三类,具体如下:
- 知名端口号(Well-Known Ports):范围为 0 - 1023,由互联网分配机构(IANA)统一管理分配,预先绑定 HTTP、FTP 等通用应用层协议,端口号固定且公开(例如 HTTP 对应 80 端口、HTTPS 对应 443 端口、SSH 对应 22 端口、FTP 对应 21 端口),常用于服务端程序监听固定端口提供服务。
- 注册端口号(Registered Ports):范围为 1024 - 49151,用于应用程序向 IANA 注册使用,非固定绑定某一协议,可作为服务端自定义服务的端口(如自定义 UdpServer 绑定的 8080 端口),避免与知名端口冲突。
- 动态端口号(Dynamic/Temporary Ports):范围为 49152 - 65535,无需注册,由操作系统为客户端程序临时分配,用于客户端与服务端建立临时网络连接;连接断开后,端口号会被释放,可再次分配给其他客户端进程。
- 端口号的核心作用是唯一标识目标主机内正在进行网络通信的进程:接收数据时,告诉操作系统当前数据包需交付给本机的哪个网络进程处理;发送数据时,操作系统会为发送进程分配源端口,供目标主机回应时定位发送方进程;
- IP 地址 + 传输层协议(TCP/UDP)+ 端口号,共同唯一标识网络上某一台主机的某一个网络进程 ------ 三者组合称为「套接字(Socket)」,是跨主机进程间通信的核心标识(仅 IP + 端口无法唯一区分,因 TCP 和 UDP 协议的端口空间相互独立);
- 在同一台主机上,同一传输层协议(TCP 或 UDP)下,一个端口号通常只能被一个网络进程独占绑定(避免端口冲突导致数据交付混乱);不同传输层协议可复用端口号(如 TCP 80 端口和 UDP 80 端口可分别被不同进程占用,互不影响)。
- 补充说明:通过
SO_REUSEADDR等 socket 选项,可实现同一端口在特定场景下的复用(如 TCP TIME_WAIT 状态下的端口快速复用),但这属于进阶配置,默认情况下仍遵循「同一协议下端口独占」规则。

2.2 理解 "端口号" 和 "进程ID"
我们之前在学习系统编程的时候,了解到 PID(进程 ID)用于标识一台主机内唯一的一个进程;此处的端口号也能用于标识主机内的网络进程,那么这两者之间是怎样的关系?
我们可以用一个通俗的例子理解:把主机比作一家快递公司,进程比作快递公司内的各个业务部门(如 10086 客服部、仓储部),PID 就是各个部门的内部办公编号(仅内部人员知晓),端口号就是各个部门的对外联系电话(客户可直接拨打)。外部客户(网络数据)无法通过内部办公编号(PID)找到对应部门,只能通过对外联系电话(端口号)精准对接,而快递公司内部(操作系统)可通过对外电话(端口号)关联到对应部门(进程)。
端口号与**进程 ID(PID)**的核心区别与关联(逻辑梳理版)
一、核心属性对比:两者定位完全不同
| 维度 | 端口号(Port Number) | 进程 ID(PID) |
|---|---|---|
| 核心定位 | 网络通信专属标识(传输层层面) | 操作系统内核进程管理专属标识(系统调度层面) |
| 核心用途 | 定位主机内的网络进程,实现数据端到端交付 | 操作系统内部调度、管理进程(如启停进程、分配资源) |
| 唯一性范围 | 同一主机 + 同一传输层协议(TCP/UDP)下唯一 | 同一主机内全局唯一(所有进程不重复) |
| 关联场景 | 仅与网络通信相关(如 Socket 绑定、数据收发) | 与网络通信无直接关联(非网络进程也有 PID) |
二、端口号与进程的核心关联(绑定规则)
- 一个网络进程可绑定多个端口号:例如 Nginx 进程可同时绑定 80 端口(HTTP 服务)和 443 端口(HTTPS 服务),通过不同端口提供多种网络服务,只需确保每个端口在对应协议下唯一即可。
- 一个端口号不能被多个进程同时绑定:在同一主机的同一传输层协议(TCP 或 UDP)下,单个端口号只能分配给一个网络进程(默认规则),避免数据交付时出现 "多进程争抢",确保数据精准送达目标进程。
三、设计逻辑:为什么用端口号而非 PID 标识网络进程?
- 解耦系统管理与网络通信:PID 是操作系统内核用于进程调度的内部标识,若直接用 PID 标识网络进程,会导致 "进程管理" 与 "网络通信" 强耦合,违背分层解耦的设计原则。
- 保障网络通信稳定性:进程重启后 PID 会被操作系统重新分配(新 PID 与旧 PID 不同),若依赖 PID 标识网络进程,会导致原有网络连接中断、服务不可用;而端口号可固定(如服务端长期绑定 80 端口),即使进程重启,绑定相同端口后仍能正常提供服务。
- 适配网络通信场景需求:端口号天然与传输层协议(TCP/UDP)关联,可精准区分同一主机上不同协议的网络服务(如 TCP 80 端口与 UDP 80 端口可独立使用),而 PID 不具备协议区分能力,无法满足网络通信的寻址需求。
总结
- 端口号是 "网络通信的专属地址",只负责数据在网络层面的进程定位;
- PID 是 "系统内部的进程身份证",只负责操作系统对进程的管理调度;
- 两者通过 "端口绑定(bind)" 建立临时关联:网络进程绑定端口后,操作系统会维护 "端口号→进程 PID" 的映射关系,实现 "网络数据→端口→进程" 的精准交付,但这种关联不改变两者各自的核心定位与用途。
2.3 理解源端口号和目的端口号
传输层协议(TCP 和 UDP)的数据段(segment)中包含两个核心端口号字段,分别叫做源端口号和目的端口号,这两个字段共同描述了网络数据的「传输轨迹」------ 明确标识 "数据是谁(哪个主机的哪个进程)发的,要发给谁(哪个主机的哪个进程)"。
3. 理解socket(套接字)
-
综上,IP 地址用来标识互联网中唯一的一台主机,端口号(port)用来标识该主机上唯一的一个网络进程;
-
完整的 "套接字地址"(网络定位标识)需满足:传输层协议(TCP/UDP)+ IP 地址 + 端口号。三者组合才能唯一标识互联网中某一台主机上的某一个网络进程。(仅 "IP 地址 + 端口号" 无法完全唯一区分,因 TCP 和 UDP 协议的端口空间相互独立)。
-
网络通信的本质是跨主机的进程间通信:即不同主机上的网络进程通过 TCP/IP 协议栈完成数据交互。而 {源 IP(srcIp)、源端口号(srcPort)、目的 IP(dstIp)、目的端口号(dstPort)、传输层协议} 构成的 "5 元组"(实际应用中常简化为 "4 元组",默认隐含传输层协议),能唯一标识互联网中一对正在进行双向交互的通信进程,精准界定一次特定的跨主机进程通信链路。
-
最终明确两个关键概念的区分与关联:
- 套接字地址(Socket Address):即 "传输层协议 + IP 地址 + 端口号" 的组合,是网络层面的 "定位标识",用于精准定位跨网络的目标进程;
- 套接字(Socket):是操作系统内核为应用程序分配的网络通信资源句柄(如文件描述符),是数据传输的 "载体";
- 当应用程序通过
bind系统调用,将 "套接字地址" 与 "套接字(内核通信资源)" 关联后,便形成了完整的网络通信端点 ------ 应用程序可通过该端点发起或接收网络数据,实现跨主机进程间的稳定通信。
建立网络通信的步骤:
- 创建套接字。
- 将IP+端口号,绑定到套接字。
- 进行send/recv(发送/接收)信息。
4. 传输层的典型代表
如果我们了解了系统,也了解了网络协议栈,我们就会清楚,传输层是属于内核的,那么我们要通过网络协议栈进行通信,必定调用的是传输层提供的系统调用,来进行的网络通信。
传输层的核心典型协议包括 UDP(用户数据报协议)和 TCP(传输控制协议),两者的底层逻辑均由操作系统内核封装实现,应用层无需关注传输层的底层细节,只需通过标准化的 socket 系统调用即可调用其传输功能。这两种协议分别适配不同的通信需求,构成了绝大多数网络应用的传输基础,下面先对两者的核心特征做直观认识:

4.1 认识 UDP 协议
此处我们也对 UDP(User Datagram Protocol,用户数据报协议)有一个直观的认识,后面再详细讨论 UDP 的核心细节与应用场景。
UDP 协议的核心直观特征及概念说明如下:
- 传输层协议:UDP 是工作在 TCP/IP 分层模型传输层的核心协议,与 TCP 同级,向下同样依赖网络层 IP 协议实现主机寻址,向上为应用层提供简单的端到端数据传输接口(如 DNS、DHCP、直播等应用层协议 / 场景常基于 UDP 实现)。
- 无连接:UDP 协议在数据传输前,通信双方无需建立任何专属连接,也无需维护连接状态;发送端可直接封装数据并发送,接收端可直接接收并处理数据,传输完成后无任何关闭连接的流程,资源开销极低。
- 不可靠传输:UDP 协议仅提供最基础的数据传输功能,不保障数据的准确、完整与有序交付,无数据重传、流量控制、拥塞控制等机制;若网络出现丢包、延迟、乱序,UDP 不会做任何补救措施,数据可能丢失或错乱,接收端甚至无法感知数据是否丢失。
- 面向数据报:UDP 协议将应用层交付的数据视为一个完整的、有边界的数据报(即一个独立的 UDP 报文),会严格按照应用层交付的数据大小进行封装,单次传输一个完整的数据报,不拆分、不拼接;发送端发送一个 UDP 数据报,接收端就只能接收一个完整的 UDP 数据报,无法按需拆分或拼接,具有明确的数据边界。
4.2 认识 TCP 协议
此处我们先对 TCP(Transmission Control Protocol,传输控制协议)有一个直观的认识,后面我们再详细讨论 TCP 的一些核心细节问题。
TCP 协议的核心直观特征及概念说明如下:
- 传输层协议:TCP 是工作在 TCP/IP 分层模型传输层的核心协议,向下依赖网络层 IP 协议提供的主机寻址与路由服务,向上为应用层提供可靠的端到端数据传输接口(如 HTTP、SSH 等应用层协议均基于 TCP 实现)。
- 有连接:在进行实际数据传输之前,通信双方的进程必须先通过 "三次握手" 建立起专属的网络连接(包含双方 IP、端口、连接状态等信息),数据传输完成后,又需通过 "四次挥手" 关闭该连接,连接全程独占相关资源。
- 可靠传输:TCP 协议通过一系列机制保障数据能够准确、完整、有序地从发送端进程交付到接收端进程,核心保障包括:数据校验、重传机制(应对丢包)、流量控制(应对接收端处理能力不足)、拥塞控制(应对网络拥堵),即使网络出现波动,也能尽可能避免数据丢失或错乱。
- 面向字节流:TCP 协议将应用层交付的数据视为一串无边界的字节序列,不限制单次传输的数据大小,仅关注字节的传输顺序和完整性;发送端可按需拆分字节流进行传输,接收端可按需拼接字节流,最终还原为完整的应用层数据,无固定的数据报文格式限制。
5. 网络字节序(大端字节序)
我们已经知道,内存中的多字节数据(如 int、long)相对于内存地址有大端、小端之分,磁盘文件中的多字节数据相对于偏移地址也存在字节序差异 ------ 网络数据流作为多字节数据的传输载体,同样面临字节序不统一的问题:不同主机(大端机 / 小端机)对多字节数据的内存存储方式不同,若直接传输会导致接收端解析错乱。因此,必须明确网络数据流的地址规则,并统一传输字节序。
一、网络数据流的地址规则
发送主机传输多字节数据时,会将发送缓冲区中的数据按 内存地址从低到高 的顺序依次发出;
接收主机接收数据时,会将网络上获取的字节序列,按 内存地址从低到高 的顺序依次存入接收缓冲区。
由此推导网络数据流的地址规则:先发出的数据对应低地址,后发出的数据对应高地址,形成有序的字节流传输序列(例如,发送缓冲区中地址 0x00 存储字节 A、0x01 存储字节 B,则网络上先传输 A,再传输 B,接收端地址 0x00 存 A、0x01 存 B)。
二、TCP/IP 协议的字节序规定
TCP/IP 协议明确规定,网络数据流必须采用++大端字节序++(也称为网络字节序),即低地址对应高字节、高地址对应低字节(例如多字节整数 0x1234abcd,在网络数据流中低地址存储 0x12,高地址存储 0xcd);
- 无论通信双方的主机是大端机还是小端机,在进行网络数据发送 / 接收时,都会严格遵循 TCP/IP 协议规定的网络字节序,确保跨主机通信的数据格式一致性;
- 如果当前发送主机是小端机(绝大多数常见主机为小端机),就需要先将待传输的多字节数据从本机小端字节序转换为大端网络字节序,再进行发送;若发送主机是大端机,其本机字节序与网络字节序一致,则无需进行字节序转换,可直接封装并发送数据。

为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换。

-
这些函数名很好记,h 表示 host,n 表示network,l 表示 32 位长整数, s 表示 16 位短整数。
-
例如htonl 表示将32 位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。
-
如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回;
-
如果主机是大端字节序,这些函数不做转换,将参数原封不动地返回。
下一讲:socket编程接口+服务端&客户端网络通信实现