侧边栏壁纸
博主头像
colo

欲买桂花同载酒

  • 累计撰写 1823 篇文章
  • 累计收到 0 条评论

实现一个支持多客户端的TCP时间服务器

2025-12-5 / 0 评论 / 4 阅读

题目

实现一个支持多客户端的TCP时间服务器

信息

  • 类型:问答
  • 难度:⭐⭐

考点

Socket编程,多线程处理,资源管理,异常处理

快速回答

实现要点:

  • 使用ServerSocket在指定端口监听
  • 循环接受客户端连接,为每个连接创建独立线程
  • 使用BufferedWriter发送当前时间后立即关闭连接
  • 使用线程池管理线程资源
  • 关键异常处理:IOException和中断异常
## 解析

原理说明

TCP时间服务器基于客户端-服务器模型:
1. 服务器通过ServerSocket持续监听端口
2. 客户端通过Socket发起连接请求
3. 每个连接独立线程处理,避免阻塞主线程
4. 遵循TCP协议保证可靠数据传输

代码示例

import java.io.*;
import java.net.*;
import java.time.LocalDateTime;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TimeServer {
    private static final int PORT = 8080;
    private static final int MAX_THREADS = 10;

    public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(MAX_THREADS);

        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("时间服务器启动,端口:" + PORT);

            while (!Thread.currentThread().isInterrupted()) {
                Socket clientSocket = serverSocket.accept();
                pool.execute(() -> handleClient(clientSocket));
            }
        } catch (IOException e) {
            System.err.println("服务器异常:" + e.getMessage());
        } finally {
            pool.shutdown();
        }
    }

    private static void handleClient(Socket socket) {
        try (BufferedWriter writer = new BufferedWriter(
                new OutputStreamWriter(socket.getOutputStream()))) {

            String response = "当前时间:" + LocalDateTime.now() + "\n";
            writer.write(response);
            writer.flush();

        } catch (IOException e) {
            System.err.println("客户端处理失败:" + e.getMessage());
        } finally {
            try {
                socket.close(); // 关键:显式关闭连接
            } catch (IOException ex) {
                System.err.println("关闭连接异常:" + ex.getMessage());
            }
        }
    }
}

最佳实践

  • 线程池管理:使用Executors.newFixedThreadPool避免线程频繁创建销毁
  • 资源释放:在finally块中确保关闭Socket(try-with-resources更佳)
  • 响应协议:发送数据后立即关闭连接符合时间服务场景
  • 优雅退出:通过Thread.currentThread().isInterrupted()检测中断信号

常见错误

  • 资源泄漏:未关闭Socket或Writer导致文件描述符耗尽
  • 线程爆炸:直接new Thread()处理连接,高并发时崩溃
  • 阻塞主线程:在handleClient中执行耗时操作
  • 编码问题:未指定字符集导致乱码(示例中依赖平台默认编码)

扩展知识

  • NIO模型:使用java.nio.channels.ServerSocketChannel实现非阻塞IO,支持更高并发
  • 协议设计:生产环境应定义消息边界(如长度前缀或分隔符)
  • 超时控制:通过socket.setSoTimeout()防止客户端无响应
  • 安全加固:对客户端IP做白名单限制,防止DDoS攻击