网络编程概述:IP、端口与通信协议 | JavaSE
网络编程概述:IP、端口与通信协议
一、学习目标
学完本章,你应该能够:
- 能够解释什么是网络编程,以及 Java 网络编程主要解决什么问题。
- 能够区分 C/S 架构与 B/S 架构。
- 能够解释网络通信中的三个核心要素:IP 地址、端口号、通信协议。
- 能够区分 IPv4、IPv6、私有地址、回环地址等常见网络地址概念。
- 能够解释端口号的作用以及常见端口范围。
- 能够从连接方式、可靠性、效率等角度初步区分 TCP 与 UDP。
- 能够使用
ipconfig、ping等基本命令辅助排查网络问题。
二、核心知识
2.1 什么是网络编程
网络编程(Network Programming)是指:
让不同设备中的程序通过计算机网络建立联系并交换数据。
例如:
客户端程序
│
│ 网络
▼
服务端程序
假设我们开发一个聊天软件:
电脑 A
Java 客户端
│
│ "你好"
▼
网络
│
▼
电脑 B
Java 服务端
程序需要解决至少几个问题:
我要找哪台电脑?
↓
IP 地址
我要找这台电脑上的哪个程序?
↓
端口号
双方按照什么规则传输数据?
↓
通信协议
因此,在 Java 网络编程入门阶段,可以把网络通信最核心的三个要素概括为:
IP 地址 + 端口号 + 通信协议
Java 中大量网络编程 API 位于:
java.net
包下。
2.2 常见网络通信架构
应用程序进行网络通信时,最常见的两种架构是:
- C/S
- B/S
C/S 架构
C/S:
Client / Server
客户端 / 服务端
结构:
┌──────────┐
│ Client │
│ 客户端 │
└────┬─────┘
│ 网络
▼
┌──────────┐
│ Server │
│ 服务端 │
└──────────┘
例如:
- QQ 客户端
- 微信客户端
- Steam
- IDEA
- 各类桌面聊天软件
开发者通常既需要开发服务端,也需要提供专门的客户端软件。
优点通常包括:
- 可以提供复杂的本地交互。
- 可以充分利用客户端计算能力。
- 可以访问更多本地系统资源。
缺点之一是:
客户端通常需要安装、更新和维护。
B/S 架构
B/S:
Browser / Server
浏览器 / 服务端
结构:
┌──────────┐
│ Browser │
│ 浏览器 │
└────┬─────┘
│ HTTP/HTTPS
▼
┌──────────┐
│ Server │
│ 服务端 │
└──────────┘
例如访问一个博客:
Chrome / Edge
↓
网络
↓
博客服务器
B/S 并不是“没有客户端”。
浏览器本身就是客户端。
它真正的特点是:
开发者通常不需要再为普通用户单独开发和安装一个专用客户端,而是利用浏览器作为通用客户端。
这也是后续 Java Web 开发的重要基础。
2.3 网络通信三要素
网络通信入门阶段最重要的模型是:
IP 地址:找到设备
端口号:找到设备中的程序/网络服务
协议:规定双方怎么通信
可以类比寄快递:
IP 地址 = 小区 + 楼栋
端口号 = 房间号
通信协议 = 双方约定的交接规则
数据 = 快递包裹
如果只有 IP:
192.168.1.20
只能知道目标设备。
但是一台计算机可能同时运行:
Web 服务
数据库
聊天服务
Redis
SSH
因此还需要端口号来进一步确定网络通信终点。
2.4 IP 地址
IP 是:
Internet Protocol
互联网协议
IP 地址用于标识网络中的接口,使网络数据能够找到目标位置。
初学阶段可以理解为:
IP 地址主要解决“数据应该发到哪台设备”这个问题。
2.5 IPv4
IPv4 地址长度为:
32 bit
通常使用点分十进制表示:
192.168.1.10
实际上:
192 . 168 . 1 . 10
↓ ↓ ↓ ↓
8bit 8bit 8bit 8bit
总共:
8 × 4 = 32 bit
每一部分范围通常为:
0 ~ 255
例如:
192.168.0.1
10.0.0.5
172.16.10.20
2.6 IPv6
IPv4 地址空间有限,因此后来出现 IPv6。
IPv6 地址长度为:
128 bit
典型表示形式:
2001:db8:85a3::8a2e:370:7334
与 IPv4 相比,IPv6 最明显的特点之一就是:
地址空间大幅扩大。
可以先记:
IPv4:32 位
IPv6:128 位
后续计算机网络课程会进一步学习 IPv6 报文结构、地址分类、子网以及路由机制。
2.7 私有 IPv4 地址
我们平时连接:
- 家庭 Wi-Fi
- 学校局域网
- 公司局域网
看到的地址经常属于私有地址空间。
IPv4 常见的三段私有地址为:
10.0.0.0
~
10.255.255.255
172.16.0.0
~
172.31.255.255
以及:
192.168.0.0
~
192.168.255.255
例如:
192.168.1.5
192.168.31.20
10.0.0.8
这些地址通常用于内部网络。
因此:
192.168.x.x
只是私有 IPv4 地址中的一部分,而不是全部。
2.8 回环地址
开发网络程序时经常看到:
127.0.0.1
以及:
localhost
127.0.0.1 是最常见的 IPv4 回环地址(Loopback Address)。
它代表:
网络数据发送给当前计算机自身的网络协议栈。
例如本机启动:
Java Server
端口 8080
然后访问:
127.0.0.1:8080
实际上就是:
本机程序
↓
本机网络协议栈
↓
本机服务
数据不需要真正发送到局域网中的其他机器。
需要特别注意:
127.0.0.1不等于“电脑网卡当前真正使用的局域网 IP”。
例如你的电脑可能同时具有:
回环地址:
127.0.0.1
Wi-Fi 地址:
192.168.1.23
它们的用途完全不同。
IPv6 中典型的回环地址为:
::1
2.9 域名与 DNS
人类很难记住大量 IP 地址,例如:
142.x.x.x
因此互联网通常使用:
域名(Domain Name)
例如:
www.example.com
但是网络真正进行 IP 层通信时仍然需要 IP 地址。
因此需要:
DNS
Domain Name System
域名系统
完成类似:
www.example.com
↓
DNS
↓
某个 IP 地址
的解析过程。
可以简单理解为:
DNS 类似互联网中的“地址簿”。
2.10 端口号
如果 IP 地址负责:
找到设备
那么端口号(Port)主要负责:
找到设备上对应的网络服务端点
例如一台服务器可能同时运行:
IP:192.168.1.100
其中:
192.168.1.100:8080
运行 Web 服务。
而:
192.168.1.100:9999
运行聊天服务。
于是:
IP
+
端口
能够进一步定位某个网络服务。
2.11 端口号范围
端口号是一个 16 位无符号数。
范围:
0 ~ 65535
通常可以分为:
| 范围 | 类型 |
| --------------- | ----------------------- |
| 0 ~ 1023 | System Ports |
| 1024 ~ 49151 | User Ports |
| 49152 ~ 65535 | Dynamic / Private Ports |
一些常见端口:
| 服务 | 常见端口 | | ----- | -------: | | HTTP | 80 | | HTTPS | 443 | | SSH | 22 | | DNS | 53 |
学习阶段自己编写服务器时,经常使用:
8080
8888
9999
等端口。
但必须注意:
端口号不是 Java 专属概念,而是 TCP、UDP 等传输层协议中的网络概念。
2.12 为什么会发生端口冲突
假设第一个 Java 程序已经监听:
TCP
192.168.1.10:9999
另一个程序再次尝试绑定同样的本地地址、TCP 协议和端口:
192.168.1.10:9999
通常就会发生:
BindException
Address already in use
因此初学阶段可以记忆:
同一个网络端点不能被不同程序随意重复占用。
不过更加准确地说,端口并不是脱离上下文单独存在的。
网络端点还与:
- IP 地址
- TCP / UDP 等传输协议
- 操作系统的 Socket 绑定规则
有关。
例如:
TCP 9999
和:
UDP 9999
是不同的传输协议端点,因此“端口号数字一样”并不必然意味着冲突。
2.13 什么是通信协议
协议(Protocol)可以理解为:
网络通信双方共同遵守的一组规则。
如果两个人:
一个只说中文
一个只说法语
即使双方找到了彼此,也无法正确交流。
计算机也是一样。
必须规定:
- 如何建立通信
- 数据怎样组织
- 数据怎样发送
- 怎样判断错误
- 怎样结束通信
这些规则共同构成各种网络协议。
2.14 TCP 与 UDP
Java 网络编程入门阶段需要重点认识两个传输层协议:
TCP
UDP
UDP
UDP:
User Datagram Protocol
用户数据报协议
主要特点:
无连接
面向数据报
协议本身不保证可靠交付
开销较小
延迟通常较低
UDP 本身不保证:
- 一定送达
- 按发送顺序到达
- 不重复
因此如果应用需要这些能力,需要自己设计相应机制,或者选择其他协议。
UDP 常用于一些特别重视实时性、能够容忍部分数据丢失的场景。
后续会专门学习:
DatagramSocket
DatagramPacket
TCP
TCP:
Transmission Control Protocol
传输控制协议
主要特点:
面向连接
可靠字节流
保证有序交付
具有重传等可靠性机制
因此常见于:
- Web 通信
- 文件传输
- 数据库连接
- 即时通信中的可靠消息
- 各种要求完整传输的数据
后续会重点学习:
Socket
ServerSocket
2.15 TCP 与 UDP 初步对比
| 对比维度 | TCP | UDP |
| ------------- | ------------------------ | ---------------------------------- |
| 是否建立连接 | 是 | 否 |
| 数据模型 | 字节流 | 数据报 |
| 可靠交付 | 提供 | 不提供 |
| 数据顺序 | 提供有序交付 | 不保证 |
| 协议开销 | 较大 | 较小 |
| 实时性 | 通常相对弱 | 通常较好 |
| Java 核心 API | Socket、ServerSocket | DatagramSocket、DatagramPacket |
现在不需要立刻掌握它们的完整工作原理。
后续章节会逐个实现。
三、使用方法
3.1 Windows 查看网络配置
Windows 可以使用:
ipconfig
查看网络接口信息。
你可能看到:
IPv4 Address . . . . . . . . . : 192.168.1.23
这个地址可能就是当前电脑 Wi-Fi 或有线网卡使用的局域网地址。
3.2 测试目标主机基本可达性
可以使用:
ping 127.0.0.1
测试本机回环。
也可以:
ping 192.168.1.10
测试局域网设备。
或者:
ping example.com
测试域名解析与基本网络连通情况。
但要注意:
ping 失败
≠
目标服务一定不可访问
因为:
- 防火墙可能屏蔽 ICMP
- 网络设备可能禁止 Ping
- 目标服务器可能主动关闭响应
因此 ping 只是网络排错工具之一。
3.3 从程序通信角度理解地址
假设我们开发一个聊天系统:
服务端:
IP:192.168.1.50
端口:9999
协议:TCP
那么客户端连接的目标可以抽象成:
TCP://192.168.1.50:9999
三个核心问题分别已经解决:
192.168.1.50
↓
找到哪台设备
9999
↓
找到哪个服务
TCP
↓
双方按照什么传输方式通信
这就是后续 Socket 编程的基础。
四、原理与进阶
4.1 IP 地址不是“某台电脑永远不变的身份证”
初学时经常说:
IP 地址唯一标识一台设备。
这是为了方便建立概念。
更加准确地说:
IP 地址属于网络接口和具体网络环境中的网络层地址。
一台电脑可能同时拥有:
127.0.0.1
192.168.1.20
某个 IPv6 地址
VPN 虚拟网卡地址
甚至连接不同网络后,其地址还可能变化。
所以不能简单理解成:
一台电脑 = 永远只有一个 IP
4.2 一个域名也不一定只有一个 IP
例如:
example.com
经过 DNS 解析时:
域名
↓
DNS
↓
可能得到一个或多个 IP 地址
大型网站通常通过:
- 多服务器
- CDN
- 负载均衡
- DNS 调度
使用多个地址提供服务。
Java 中后续可以通过:
InetAddress.getAllByName(...)
观察这种情况。
4.3 网络通信的层次
本章使用:
IP + 端口 + 协议
作为网络编程入门模型。
但完整计算机网络实际上存在更复杂的分层体系。
例如常见 TCP/IP 模型可以抽象为:
应用层
↓
传输层
↓
网络层
↓
网络接口层
例如:
HTTP
↓
TCP
↓
IP
↓
以太网 / Wi-Fi
JavaSE 网络编程主要从应用程序角度接触:
TCP
UDP
IP 地址
Socket
至于:
- 路由
- ARP
- TCP 拥塞控制
- 子网划分
- MAC 地址
- NAT
- DNS 递归解析
等内容,可以在计算机网络课程中系统深入。
五、实践应用
5.1 Java 服务端
后面我们将编写:
Java Server
监听:
9999
等待其他客户端连接。
5.2 局域网即时通信
假设:
电脑 A:
192.168.1.20
电脑 B:
192.168.1.30
电脑 B 运行 Java 服务端:
192.168.1.30:9999
电脑 A 就可以使用网络编程 API 与它通信。
最终可以逐步发展为:
客户端 A ─┐
客户端 B ─┼──→ Java Server
客户端 C ─┘
再结合刚刚学习完成的:
多线程
线程池
IO 流
就能构建一个真正的多客户端网络服务。
这也是为什么 JavaSE 的课程顺序通常是:
IO
↓
多线程
↓
网络编程
三者最终会在服务端程序中组合起来。
六、常见问题
6.1 IP 地址和端口有什么区别?
IP:
定位网络中的设备/网络接口
端口:
定位该主机上的传输层服务端点
简单记忆:
IP 找电脑
端口找程序
这是入门阶段非常实用的理解方式。
6.2 localhost 就是电脑当前 Wi-Fi IP 吗?
不是。
localhost 通常指向回环地址。
IPv4 常见:
127.0.0.1
而当前 Wi-Fi 地址可能是:
192.168.1.23
两者用途不同。
6.3 192.168 开头的地址一定是公网 IP 吗?
不是。
192.168.0.0/16
属于 IPv4 私有地址空间。
6.4 一个程序只能有一个端口吗?
不是。
一个程序完全可能:
- 打开多个 Socket
- 监听多个端口
- 同时发起很多网络连接
因此:
程序 ≠ 一个固定端口
6.5 两个程序端口数字相同一定冲突吗?
不能仅看数字。
需要考虑:
IP
传输协议
端口
Socket 绑定规则
例如:
TCP 9999
和:
UDP 9999
不是同一个传输层端点。
6.6 UDP 是不是一定比 TCP 快?
不能简单绝对化。
UDP:
协议机制更轻量
但应用的实际性能还取决于:
- 网络状况
- 数据规模
- 应用层实现
- 丢包率
- 重传机制
- 延迟要求
因此更准确的说法是:
UDP 协议本身开销较小,而 TCP 提供了更多可靠性机制。
6.7 为什么学习 Java 网络编程之前要学 IO?
因为网络连接建立后,本质上仍然需要:
读取数据
写出数据
尤其 TCP Socket 编程中,我们会直接接触:
InputStream
OutputStream
之前学习的 IO 流会重新出现。
6.8 为什么网络编程又需要多线程?
如果服务端只有一个线程:
客户端 A
↓
Server
处理客户端 A 时可能无法及时处理:
客户端 B
客户端 C
客户端 D
因此常见服务器模型会组合:
网络连接
+
多线程
+
线程池
+
IO
这就是前面几大 JavaSE 模块最终开始汇合的地方。
七、练习与验收
7.1 知识问答
- 什么是网络编程?Java 网络 API 主要位于哪个包?
- 网络通信为什么需要 IP、端口和协议?
- IP 地址与端口号分别解决什么问题?
- IPv4 和 IPv6 地址长度分别是多少?
127.0.0.1是什么地址?localhost与本机当前局域网 IP 是同一个概念吗?- IPv4 私有地址空间主要有哪些范围?
- DNS 解决什么问题?
- TCP 与 UDP 的主要区别是什么?
- 为什么不能简单说“两个程序绝对不能使用相同的端口数字”?
7.2 代码阅读
观察下面的网络服务描述:
协议:TCP
IP:192.168.1.100
端口:9999
回答:
192.168.1.100负责解决什么问题?9999负责解决什么问题?- TCP 在这里承担什么作用?
- 如果目标 IP 错误,客户端可能出现什么现象?
- 如果 IP 正确但端口错误,又意味着什么?
7.3 手写代码
本章暂时不要求正式 Socket 编程。
完成以下命令实践:
ipconfig
记录当前电脑至少一个 IPv4 地址。
然后分别执行:
ping 127.0.0.1
ping localhost
再选择一个可访问域名:
ping 域名
比较执行结果。
7.4 Debug
某同学说:
我的电脑 IP 就是
127.0.0.1,所以其他同学连接我的服务器时只要访问127.0.0.1:9999就能连接到我的电脑。
判断该说法是否正确。
要求说明:
127.0.0.1的真正含义。- 另一台电脑访问自己的
127.0.0.1时实际访问的是谁。 - 局域网通信时应该寻找什么地址。
7.5 综合训练
假设宿舍中有两台电脑:
电脑 A:192.168.1.10
电脑 B:192.168.1.20
电脑 B 上运行一个 TCP 聊天服务:
端口:9999
请画出:
客户端
IP
端口
协议
服务端
之间的关系,并说明客户端要成功发送消息至少需要知道哪些信息。
7.6 本章验收
如果你能够闭卷解释:
网络编程
C/S
B/S
IPv4
IPv6
私有地址
回环地址
DNS
IP
端口
TCP
UDP
并能完整回答:
“客户端究竟是如何定位到网络上另一个 Java 服务端程序的?”
那么本章核心知识已经掌握。
最终必须建立这个模型:
网络通信
┌────────┴────────┐
│ │
找设备 找服务
│ │
IP Port
│ │
└────────┬────────┘
│
Protocol
│
按规则传输数据