Java中ServerSocket接收客户端连接的核心是创建绑定端口的ServerSocket、调用阻塞的accept()等待三次握手完成并返回Socket对象。1. 创建时指定未占用端口(避开1–1023)、可选backlog和绑定IP;2. accept()循环调用并配合多线程/线程池处理多客户端;3. 必须显式关闭资源,推荐try-with-resources;4. 常见问题包括防火墙拦截、端口占用、未启动客户端及单线程串行化,需针对性排查与优化。

Java 中通过 ServerSocket 接收客户端连接请求,核心是创建服务端套接字、绑定端口、调用 accept() 阻塞等待连接——只要客户端成功发起 TCP 连接(如用 Socket 连接该地址和端口),accept() 就会返回一个代表该连接的 Socket 对象,后续通信就基于它进行。
1. 创建并绑定 ServerSocket
指定监听的端口号(需未被占用,且普通用户通常避开 1–1023),可选绑定本地 IP(默认绑定所有可用网卡):
-
注意端口冲突:若端口已被占用,构造时抛出
IOException - 推荐显式指定
backlog(如new ServerSocket(port, 50)),控制等待连接的队列长度,避免突发连接被拒绝 - 如需绑定特定网卡(如只响应内网请求),用
new ServerSocket(port, backlog, InetAddress.getByName("192.168.1.100"))
2. 调用 accept() 等待并接收连接
accept() 是阻塞方法,线程会一直等待,直到有客户端完成三次握手:
- 返回值是
Socket对象,封装了与该客户端的完整 TCP 连接(含输入流、输出流、远程地址等) - 每次
accept()只处理一个连接;若要支持多客户端,必须在循环中反复调用,或为每个连接启动新线程/交给线程池处理 - 示例片段:
ServerSocket server = new ServerSocket(8080);<br> while (true) {<br> Socket client = server.accept(); // 阻塞至此<br> // 处理 client,例如 new Thread(() -> handle(client)).start();<br> }
3. 正确关闭资源防止泄漏
ServerSocket 和每个 Socket 都需显式关闭,否则端口可能无法立即重用,系统资源持续占用:
立即学习“Java免费学习笔记(深入)”;
- 使用 try-with-resources 自动关闭(推荐):
try (ServerSocket server = new ServerSocket(8080)) {<br> while (!Thread.interrupted()) {<br> try (Socket client = server.accept()) {<br> handle(client);<br> }<br> }<br> } - 手动关闭时,先关 client Socket,再关 ServerSocket;关闭 ServerSocket 后,
accept()会抛出SocketException
4. 常见问题与应对
实际开发中容易忽略的细节:
-
客户端连不上? 检查防火墙、端口是否被其他程序占用、服务端是否真正在运行、IP 地址是否正确(本地测试用
127.0.0.1,跨机测试确认服务端 IP 和网络可达) -
accept() 不返回? 很可能是客户端根本没调用
new Socket(host, port),或连接被中间设备拦截 -
多个客户端怎么处理? 单线程轮询 accept + 单线程处理会串行化;务必用多线程、线程池,或升级到 NIO(
Selector)实现单线程高并发 -
想立刻响应连接但不阻塞主线程? 把
accept()放进独立线程,或设置server.setSoTimeout(5000)让其超时返回,配合循环重试(适合需要定期检查停止信号的场景)



















