08-网络编程与设计模式
对应原始资料:
JavaSE进阶_day12
一、网络编程三要素
- IP 地址:唯一标识网络中的设备。
- IPv4:4 字节,如
192.168.1.1。 - IPv6:16 字节,更充足。
127.0.0.1/localhost本机回环。
- IPv4:4 字节,如
- 端口号:标识设备上的程序,2 字节 0~65535。0~1023 被系统占用。
- 协议:通信规则。
- 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 底层,见反射章节。
练习建议
- 用 TCP 模拟聊天室(多线程 + 循环接收)。
- 实现文件上传服务(线程池版)。
- 写饿汉、懒汉、静态内部类三种单例,多线程测试。
- 用装饰者模式给一杯咖啡动态添加配料(牛奶、糖),计算最终价格。
- 用简单工厂创建不同形状(Shape)对象。