Skip to content

08-网络编程与设计模式

对应原始资料:JavaSE进阶_day12

一、网络编程三要素

  1. IP 地址:唯一标识网络中的设备。
    • IPv4:4 字节,如 192.168.1.1
    • IPv6:16 字节,更充足。
    • 127.0.0.1 / localhost 本机回环。
  2. 端口号:标识设备上的程序,2 字节 0~65535。0~1023 被系统占用。
  3. 协议:通信规则。
    • UDP:无连接、不可靠、快,限制 64KB。适合直播、视频会议。
    • TCP:面向连接、可靠(三次握手四次挥手)、大数据。

二、InetAddress

java
InetAddress local = InetAddress.getLocalHost();
InetAddress baidu = InetAddress.getByName("www.baidu.com");
baidu.getHostAddress();

三、UDP 编程

DatagramSocket 收发数据报 DatagramPacket

发送方:

java
DatagramSocket ds = new DatagramSocket();
byte[] data = "hello".getBytes();
DatagramPacket p = new DatagramPacket(data, data.length,
        InetAddress.getByName("127.0.0.1"), 10000);
ds.send(p);
ds.close();

接收方:

java
DatagramSocket ds = new DatagramSocket(10000);
byte[] buf = new byte[1024];
DatagramPacket p = new DatagramPacket(buf, buf.length);
ds.receive(p);   // 阻塞
System.out.println(new String(p.getData(), 0, p.getLength()));

四、TCP 编程(重点)

ServerSocket(服务端)+ Socket(客户端)。

1. 客户端

java
Socket socket = new Socket("127.0.0.1", 10000);
OutputStream os = socket.getOutputStream();
os.write("你好".getBytes());
InputStream is = socket.getInputStream();
byte[] buf = new byte[1024];
int len = is.read(buf);
System.out.println(new String(buf, 0, len));
socket.close();

2. 服务端

java
ServerSocket ss = new ServerSocket(10000);
while (true) {
    Socket s = ss.accept();             // 阻塞,等待连接
    new Thread(() -> handle(s)).start(); // 多线程处理每个客户端
}

3. 经典案例:文件上传

  • 客户端读文件 → 通过 Socket 发送 → 服务端保存到磁盘 → 回写"上传成功"。
  • 注意:客户端发完要 socket.shutdownOutput(),否则服务端 read 阻塞。
  • 推荐用线程池管理并发连接。

五、设计模式

1. 单例模式(Singleton)

保证一个类在内存中只有一个对象。

饿汉式(线程安全)

java
public class Singleton {
    private static final Singleton INSTANCE = new Singleton();
    private Singleton() {}
    public static Singleton getInstance() { return INSTANCE; }
}

懒汉式(双重检查锁,线程安全)

java
public class Singleton {
    private static volatile Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) instance = new Singleton();
            }
        }
        return instance;
    }
}

volatile 防止指令重排;双重 if 避免无谓加锁。

静态内部类(推荐,懒加载 + 线程安全)

java
public class Singleton {
    private Singleton() {}
    private static class Holder { static final Singleton INSTANCE = new Singleton(); }
    public static Singleton getInstance() { return Holder.INSTANCE; }
}

最佳:枚举(防反射、防序列化破解)。

2. 多例模式(Multiton)

固定数量的实例(如固定颜色的 Color、数据源)。本质是 Map 缓存若干实例。

3. 工厂模式(Factory)

把对象创建交给工厂,解耦。

简单工厂

java
class AnimalFactory {
    public static Animal create(String type) {
        if ("dog".equals(type)) return new Dog();
        if ("cat".equals(type)) return new Cat();
        return null;
    }
}

工厂方法:每个产品对应一个工厂类。

抽象工厂:一组相关产品(如套餐)。

4. 装饰者模式(Decorator)

动态给对象增强功能,避免子类膨胀。IO 流的设计就是装饰者模式。

java
Reader r = new BufferedReader(new FileReader("a.txt"));
// FileReader = 被装饰者
// BufferedReader = 装饰者(增强:缓冲 + readLine)

与静态代理 / 适配器的区别:

  • 装饰者:增强,接口相同。
  • 代理:控制访问。
  • 适配器:接口转换。

5. 模板方法模式

父类定义算法骨架(final 模板方法),子类重写抽象步骤。详见进阶 01 章。

6. 代理模式

  • 静态代理:手动写代理类。
  • 动态代理:JDK Proxy(接口)/ CGLIB(类)。Spring AOP 底层,见反射章节。

练习建议

  1. 用 TCP 模拟聊天室(多线程 + 循环接收)。
  2. 实现文件上传服务(线程池版)。
  3. 写饿汉、懒汉、静态内部类三种单例,多线程测试。
  4. 用装饰者模式给一杯咖啡动态添加配料(牛奶、糖),计算最终价格。
  5. 用简单工厂创建不同形状(Shape)对象。