在现代互联网应用中,几乎所有服务都离不开网络通信。Java 提供了功能强大的网络编程 API,支持 TCP、UDP 等多种协议,可广泛应用于:
arduino复制编辑 ┌─────────────┐
│ Client │
└────┬────────┘
│ Socket
┌────▼────┐
│ 网络 │
└────┬────┘
│ ServerSocket
┌────▼────┐
│ Server │
└─────────┘
类名 | 功能说明 |
---|---|
Socket | 客户端,用于连接服务端 |
ServerSocket | 服务端,用于监听客户端连接请求 |
InetAddress | IP 地址类 |
java复制编辑ServerSocket serverSocket = new ServerSocket(8888);
Socket clientSocket = serverSocket.accept(); // 阻塞等待连接
InputStream in = clientSocket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String msg = reader.readLine();
System.out.println("收到客户端信息:" + msg);
java复制编辑Socket socket = new Socket("localhost", 8888);
OutputStream out = socket.getOutputStream();
PrintWriter writer = new PrintWriter(out, true);
writer.println("Hello Server!");
arduino复制编辑Client Server
↓ ↓
创建 Socket 创建 ServerSocket
↓ ↓
连接 Server(connect) 接收连接(accept)
↓ ↓
发送数据 →→→→→→→→→→→→→→→ 接收数据
←←←←←←←←←←←←←←← 发送响应
关闭连接 关闭连接
单线程服务器在客户端并发量大时会被阻塞。通过为每个客户端连接分配线程,可实现多客户端并发通信。
java复制编辑while (true) {
Socket client = serverSocket.accept();
new Thread(() -> handleClient(client)).start();
}
java复制编辑public void handleClient(Socket client) {
try (BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()))) {
String msg;
while ((msg = in.readLine()) != null) {
System.out.println("收到:" + msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
特性 | TCP | UDP |
---|---|---|
是否连接 | 是 | 否 |
传输可靠性 | 高(有重传) | 低(可能丢包) |
传输效率 | 较低(握手、确认) | 高(无连接、无确认) |
应用示例 | Web、SSH、FTP | 视频会议、DNS、游戏 |
java复制编辑DatagramSocket socket = new DatagramSocket();
byte[] data = "Hello UDP".getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("localhost"), 9999);
socket.send(packet);
java复制编辑DatagramSocket socket = new DatagramSocket(9999);
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
System.out.println("接收到 UDP 数据:" + new String(packet.getData(), 0, packet.getLength()));
lua复制编辑 +----------------------+ +------------------+
| TCP 应用 | | UDP 应用 |
+----------------------+ +------------------+
| HTTP / HTTPS | | 在线游戏 |
| 文件传输(FTP) | | 实时语音通话 |
| 远程登录(SSH) | | 视频会议 |
+----------------------+ +------------------+
多个小数据包被合并为一个发送,接收方无法区分边界。
一个大的数据包被拆成多段接收,数据不完整。
java复制编辑ExecutorService threadPool = Executors.newCachedThreadPool();
while (true) {
Socket client = serverSocket.accept();
threadPool.execute(() -> handleClient(client));
}
优势:
java复制编辑FileInputStream fis = new FileInputStream("file.txt");
OutputStream out = socket.getOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
java复制编辑InputStream in = client.getInputStream();
FileOutputStream fos = new FileOutputStream("recv.txt");
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
java复制编辑List<Socket> clientList = new CopyOnWriteArrayList<>();
当收到某个客户端消息后广播:
java复制编辑for (Socket s : clientList) {
new PrintWriter(s.getOutputStream(), true).println(msg);
}
Java NIO 提供了非阻塞通信能力,适合百万连接场景。
java复制编辑Selector selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.bind(new InetSocketAddress(8888));
serverChannel.configureBlocking(false);
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
通过 selector 监听多个客户端 channel,实现非阻塞接入。
问题 | 原因分析 |
---|---|
Connection refused | 服务端未启动或端口错误 |
数据接收阻塞 | 对方未发送或未 flush 输出流 |
Socket closed 异常 | 客户端/服务端提前关闭连接 |
粘包数据不完整 | 协议未规范,缺乏边界标识 |
arduino复制编辑Server Client
┌──────────────┐ ┌──────────────┐
│ ServerSocket │ │ Socket │
└──────┬───────┘ └──────┬───────┘
│ 接受连接 │ 连接服务器
┌──────▼───────┐ ┌───────▼────────┐
│ 多线程处理器 │ ←─────────────→│ 数据发送/接收 │
└──────────────┘ └────────────────┘
面试题 | 简要说明 |
---|---|
TCP 与 UDP 区别? | TCP 可靠连接,UDP 无连接、快但不可靠 |
粘包/拆包的本质? | 传输无边界,需要额外协议解析 |
多线程 Socket 通信的实现原理? | 每个连接一个线程或使用线程池 |
Socket 与 HTTP 的关系? | HTTP 协议基于 TCP Socket 实现 |
Java 中如何实现心跳机制? | 客户端定时发送消息,服务端监测超时 |
Java 网络编程涵盖了:
掌握这些内容,能让你开发出具备真实通信能力的 Java 应用程序,是进阶后端开发的重要一环。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。