Java Socket 类
Socket(套接字)是网络通信的基本构建块,它允许不同计算机之间通过网络进行数据交换。
在 Java 中,java.net.Socket
类提供了实现网络通信的客户端功能。
你可以把 Socket 想象成两个电话之间的连接:
- 一端是客户端(打电话的人)
- 另一端是服务器(接电话的人)
- 连接建立后,双方就可以互相发送和接收信息
Socket 类的基本用法
创建 Socket 连接
要创建一个 Socket 连接,你需要指定服务器的地址和端口:
实例
try {
// 连接到 localhost 的 8080 端口
Socket socket = new Socket("localhost", 8080);
// 使用 socket 进行通信...
// 关闭连接
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
// 连接到 localhost 的 8080 端口
Socket socket = new Socket("localhost", 8080);
// 使用 socket 进行通信...
// 关闭连接
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
主要方法
Socket 类提供了多个重要方法:
方法 | 描述 |
---|---|
getInputStream() |
获取输入流,用于接收数据 |
getOutputStream() |
获取输出流,用于发送数据 |
close() |
关闭 Socket 连接 |
isConnected() |
检查连接是否已建立 |
setSoTimeout(int timeout) |
设置超时时间(毫秒) |
实现客户端-服务器通信
客户端示例
实例
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) {
try {
// 1. 创建 Socket 连接
Socket socket = new Socket("localhost", 12345);
// 2. 获取输出流,向服务器发送数据
PrintWriter out = new PrintWriter(
socket.getOutputStream(), true);
out.println("Hello Server!");
// 3. 获取输入流,接收服务器响应
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String response = in.readLine();
System.out.println("Server response: " + response);
// 4. 关闭连接
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.net.*;
public class Client {
public static void main(String[] args) {
try {
// 1. 创建 Socket 连接
Socket socket = new Socket("localhost", 12345);
// 2. 获取输出流,向服务器发送数据
PrintWriter out = new PrintWriter(
socket.getOutputStream(), true);
out.println("Hello Server!");
// 3. 获取输入流,接收服务器响应
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String response = in.readLine();
System.out.println("Server response: " + response);
// 4. 关闭连接
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务器端示例
服务器端需要使用 ServerSocket
类:
实例
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) {
try {
// 1. 创建 ServerSocket,监听指定端口
ServerSocket serverSocket = new ServerSocket(12345);
System.out.println("Server started. Waiting for client...");
// 2. 等待客户端连接
Socket clientSocket = serverSocket.accept();
System.out.println("Client connected.");
// 3. 获取输入流,读取客户端消息
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
String message = in.readLine();
System.out.println("Client says: " + message);
// 4. 获取输出流,向客户端发送响应
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true);
out.println("Hello Client!");
// 5. 关闭连接
clientSocket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.net.*;
public class Server {
public static void main(String[] args) {
try {
// 1. 创建 ServerSocket,监听指定端口
ServerSocket serverSocket = new ServerSocket(12345);
System.out.println("Server started. Waiting for client...");
// 2. 等待客户端连接
Socket clientSocket = serverSocket.accept();
System.out.println("Client connected.");
// 3. 获取输入流,读取客户端消息
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
String message = in.readLine();
System.out.println("Client says: " + message);
// 4. 获取输出流,向客户端发送响应
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true);
out.println("Hello Client!");
// 5. 关闭连接
clientSocket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Socket 的高级特性
设置超时
实例
Socket socket = new Socket();
// 设置连接超时为 5 秒
socket.connect(new InetSocketAddress("example.com", 80), 5000);
// 设置读取超时为 3 秒
socket.setSoTimeout(3000);
// 设置连接超时为 5 秒
socket.connect(new InetSocketAddress("example.com", 80), 5000);
// 设置读取超时为 3 秒
socket.setSoTimeout(3000);
保持连接
实例
// 启用 TCP 保持活动机制
socket.setKeepAlive(true);
socket.setKeepAlive(true);
缓冲区大小
实例
// 设置接收缓冲区大小(字节)
socket.setReceiveBufferSize(8192);
// 设置发送缓冲区大小(字节)
socket.setSendBufferSize(8192);
socket.setReceiveBufferSize(8192);
// 设置发送缓冲区大小(字节)
socket.setSendBufferSize(8192);
常见问题与解决方案
连接被拒绝
- 检查服务器是否正在运行
- 确认端口号是否正确
- 检查防火墙设置
连接超时
- 检查网络连接
- 增加超时时间
- 确认服务器地址是否正确
数据接收不完整
- 确保双方使用相同的协议
- 检查缓冲区大小是否足够
- 考虑使用定界符或固定长度消息
实际应用场景
Socket 编程在实际中有广泛应用:
- 即时通讯应用(如微信、QQ)
- 在线游戏
- 远程控制软件
- 文件传输工具
- 物联网设备通信
最佳实践
- 总是处理 IO 异常
- 使用 try-with-resources 确保资源释放
- 为重要操作设置合理的超时
- 考虑使用线程池处理多个连接
- 设计清晰的通信协议
点我分享笔记