☕ 第十三章 网络编程
📄 一句话概括

网络通信 = 寄快递:IP 找到哪台电脑(楼牌号)、端口找到哪个程序(房间号)、协议约定怎么传(快递规则)。三要素齐了,Java 才能拿 Socket 插上网络说话。

前面十二章,我们的程序都是单机自嗨——数据在内存和硬盘之间倒腾。这一章开始,程序要出远门:你的 Java 程序和别人的程序隔着网络聊天,聊天工具就是网络编程。

一、先立寄快递比喻:三要素

两台电脑要传数据,和两个城市寄快递一模一样:

要素 快递比喻 长什么样
IP 地址 楼牌号——找到哪台电脑 IPv4 四段数字:192.168.1.10,每段 0~255
端口号 房间号——找到电脑里哪个程序 0~65535 的整数;一台电脑上端口不能重复用
协议 快递规则——约定怎么传 TCP / UDP(下面细说)
💡 两个必背的特殊值

127.0.0.1(localhost)= 本机自己——测试程序不用真找别人,先跟自己聊天。常用知名端口:80(网页 http)、443(https)、3306(MySQL,JDBC 章那位老熟人)。开发时自定义端口避开 1024 以下(系统留着),常用 6666、8888、9999 这种好记的。

二、IP 地址细看

三、协议:TCP 与 UDP 两兄弟

TCP——打电话:先拨号(三次握手:喂听得到吗 → 听得到你呢 → 我也 OK),接通才说话;说丢了我重讲、顺序错了我重来。可靠,但握手有开销。网页、文件下载、MySQL 连接全是它。

UDP——寄明信片:写好地址直接扔邮筒,不管对方在不在家;快、开销小,但可能丢、可能乱序。视频直播丢一帧无所谓、游戏实时对局——丢得起就用它。

对比 TCP UDP
连接 面向连接(先握手) 无连接(直接发)
可靠性 可靠(确认+重发+有序) 不可靠(尽力而为)
速度 稍慢 快
场景 网页/下载/数据库 直播/游戏/语音

四、Socket:Java 的插座

Java 不会让你去摸网线——它把「IP + 端口」打包成一个对象叫 Socket(插座):通信两端各自插一个 Socket,插上了就能读写流。注意这句:读写流——第十章 IO 的全部本事(字节流、缓冲流、转换流)在网络上原封不动继续用,Socket 只是给流换了个水源。所以 IO 那章学得越扎实,网络编程越轻松。

五、动手:Demo22 与三个 30 秒实验

先认识网络编程第一个类 InetAddress(代表一个 IP 对象):

import java.net.InetAddress;

public class Demo22 {
    public static void main(String[] args) throws Exception {
        InetAddress local = InetAddress.getLocalHost();
        System.out.println("本机名:" + local.getHostName());   // 电脑名
        System.out.println("本机IP:" + local.getHostAddress()); // 如 192.168.1.10

        InetAddress baidu = InetAddress.getByName("www.baidu.com");
        System.out.println("百度的IP:" + baidu.getHostAddress());
        System.out.println("通不通:" + baidu.isReachable(2000)); // 2 秒内能 ping 通吗
    }
}
💡 看到什么算成功

打印出你电脑的名字和 IP;getByName("www.baidu.com") 能解析出一串 IP(每次可能不一样,正常——大网站有很多服务器);isReachable 多半是 true。

三个小实验:

  1. 命令行敲 ipconfig——对照 Demo22 打印的 IP,认识「本机在局域网里的门牌」
  2. ping 127.0.0.1——永远通,体会回环地址
  3. 把 getByName 里的网址改成乱写的 www.abc123xyz999.com——抛 UnknownHostException(查无此人,受检异常,5.2 判定法:怪外部环境,第 N 次验证)

六、常见误区

  1. 「IP 就能定位程序」——错。IP 只到电脑这台机器,同一台电脑上微信、浏览器、IDEA 都在收数据,靠端口区分该给谁。
  2. 「端口随便挑个大的就行」——1024 以下大多被系统占用,选 1024 以上的空闲端口;端口冲突=程序起不来(BindException)。
  3. 「TCP 比 UDP 好」——没有好坏只有合适:要可靠选 TCP,要实时丢得起选 UDP,直播用 TCP 反而卡成 PPT。
  4. 「127.0.0.1 是特殊设备」——它是本机回环地址,永远是你自己,测试阶段的好朋友。
  5. 「网络编程要学底层协议细节」——Java 把脏活都封装好了,你只需要会用 Socket + 流;协议细节是进阶课的事。

七、自测题(先自己想,再展开)

❓ Q1:A 给 B 发数据,为什么 IP 和端口缺一不可?

IP 定位哪台电脑(快递到楼),端口定位电脑里哪个程序(快递到房间)。只有 IP:包裹到了大楼不知道敲哪个门;只有端口:连楼都找不到。

❓ Q2:MySQL 默认端口 3306,浏览器访问网页默认 80——这两个数字起什么作用?

它们是目标程序的房间号:浏览器默认往服务器的 80 号房间敲门要网页,JDBC 往 3306 号房间找 MySQL。改了端口就得显式写出来(localhost:3306 见过吧)。

❓ Q3:直播为什么用 UDP 而不用更可靠的 TCP?

直播要实时:TCP 丢一帧要停下重发,画面越等越卡;UDP 丢一帧就丢,直接播下一帧,观感流畅。丢得起的场景宁可快不要稳。

❓ Q4:Socket 和第十章的流是什么关系?

Socket 是网络两端的插座(IP+端口的封装);插上之后,socket.getInputStream() / getOutputStream() 拿到的就是普通流——读写网络 = 读写流,IO 的复制、缓冲、编码转换全套直接复用。

❓ Q5(毕业题):本机模拟「两个人聊天」需要几步?

不用第二台电脑:一台机器上两个程序用 127.0.0.1 + 一个约定端口(如 8888)就能互聊。预习思路:一个程序用 ServerSocket(8888) 开门等人(服务端),另一个用 new Socket("127.0.0.1", 8888) 上门(客户端)——具体写法下节见真章。

下一步学什么

相关笔记