在现代软件开发中,客户端与服务器之间的通信是常见需求。无论是浏览器访问网页,还是移动端请求后端服务,都离不开网络编程。
Java 原生提供了完善的网络编程支持,核心类库包括:
Socket
:用于客户端通信
ServerSocket
:用于服务器端监听请求
InetAddress
、URL
、HttpURLConnection
等工具类
本篇将通过图文与实战,带你掌握 Java 网络通信的本质原理与核心用法。
举例:127.0.0.1:8080 表示本机上监听 8080 端口的服务
📷 图示:IP 与端口关系
yaml复制编辑|----127.0.0.1----|
| 服务1: 8080 |
| 服务2: 3306 |
| 服务3: 5000 |
📷 Socket 通信流程图
markdown复制编辑客户端(Socket) →→→ 服务器(ServerSocket)
↓ ↑
发送请求 接收请求 + 回复响应
类名 | 作用 |
---|---|
Socket | 客户端通信套接字 |
ServerSocket | 服务器监听套接字 |
InetAddress | 表示 IP 地址 |
InputStream / OutputStream | 网络输入输出 |
java复制编辑Socket socket = new Socket("localhost", 8888);
java复制编辑OutputStream out = socket.getOutputStream();
out.write("Hello Server".getBytes());
java复制编辑InputStream in = socket.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println("来自服务器:" + new String(buf, 0, len));
java复制编辑socket.close();
📷 图示:客户端通信步骤
复制编辑建立连接 → 发送数据 → 等待响应 → 关闭连接
java复制编辑ServerSocket server = new ServerSocket(8888);
System.out.println("服务器启动,等待连接...");
Socket client = server.accept(); // 阻塞等待
java复制编辑InputStream in = client.getInputStream();
byte[] buffer = new byte[1024];
int len = in.read(buffer);
System.out.println("客户端说:" + new String(buffer, 0, len));
java复制编辑OutputStream out = client.getOutputStream();
out.write("你好,客户端".getBytes());
📷 图示:服务器监听和响应
复制编辑启动 ServerSocket → 等待连接 → 接收请求 → 回复响应
java复制编辑public class ChatServer {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(9999);
System.out.println("聊天服务器已启动");
while (true) {
Socket client = server.accept();
new Thread(() -> {
try {
InputStream in = client.getInputStream();
OutputStream out = client.getOutputStream();
out.write("欢迎加入聊天\n".getBytes());
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
System.out.println("用户消息:" + new String(buffer, 0, len));
out.write("已收到\n".getBytes());
}
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
}
java复制编辑public class ChatClient {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("localhost", 9999);
OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();
Scanner scanner = new Scanner(System.in);
new Thread(() -> {
try {
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) != -1) {
System.out.println("服务器说:" + new String(buf, 0, len));
}
} catch (Exception e) {
e.printStackTrace();
}
}).start();
while (scanner.hasNext()) {
String msg = scanner.nextLine();
out.write((msg + "\n").getBytes());
}
}
}
📷 图示:客户端与多线程服务器通信结构
css复制编辑[客户端] ←→ [服务线程1]
←→ [服务线程2]
←→ [服务线程N]
问题 | 处理建议 |
---|---|
连接超时 | 设置 socket.setSoTimeout(ms) |
客户端掉线 | 捕获 IOException |
服务端重启 | 客户端重连机制 |
数据错位 | 使用协议帧、换行符、标记位解析 |
技术 | 说明 |
---|---|
NIO | 非阻塞 IO(更高性能) |
Netty | Java 高性能网络框架 |
HTTPClient | 发送 HTTP 请求 |
WebSocket | 实时通信协议,基于 TCP |
Q1:一个端口可以被多个 ServerSocket 同时监听吗? A1:不可以,一个端口只能被一个服务绑定。
Q2:Socket 连接断开后怎么重连? A2:捕获异常后,尝试重新创建 Socket 并连接。
Q3:如何避免消息粘包或拆包? A3:使用固定格式、分隔符、协议标识位进行解析。
本文详细介绍了 Java 网络编程的基础理论与实战操作,涵盖:
✅ Socket 与 ServerSocket 通信机制 ✅ 网络输入输出的完整代码示例 ✅ 聊天室程序实现(多线程 + 输入输出) ✅ 网络异常处理和进阶路径指引
📌 推荐进一步学习方向:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。