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();
}

主要方法

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();
        }
    }
}

服务器端示例

服务器端需要使用 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();
        }
    }
}

Socket 的高级特性

设置超时

实例

Socket socket = new Socket();
// 设置连接超时为 5 秒
socket.connect(new InetSocketAddress("example.com", 80), 5000);
// 设置读取超时为 3 秒
socket.setSoTimeout(3000);

保持连接

实例

// 启用 TCP 保持活动机制
socket.setKeepAlive(true);

缓冲区大小

实例

// 设置接收缓冲区大小(字节)
socket.setReceiveBufferSize(8192);
// 设置发送缓冲区大小(字节)
socket.setSendBufferSize(8192);

常见问题与解决方案

连接被拒绝

  • 检查服务器是否正在运行
  • 确认端口号是否正确
  • 检查防火墙设置

连接超时

  • 检查网络连接
  • 增加超时时间
  • 确认服务器地址是否正确

数据接收不完整

  • 确保双方使用相同的协议
  • 检查缓冲区大小是否足够
  • 考虑使用定界符或固定长度消息

实际应用场景

Socket 编程在实际中有广泛应用:

  • 即时通讯应用(如微信、QQ)
  • 在线游戏
  • 远程控制软件
  • 文件传输工具
  • 物联网设备通信

最佳实践

  1. 总是处理 IO 异常
  2. 使用 try-with-resources 确保资源释放
  3. 为重要操作设置合理的超时
  4. 考虑使用线程池处理多个连接
  5. 设计清晰的通信协议