最常用方式是直接用构造方法绑定端口,如new serversocket(8080),会立即绑定到0.0.0.0:8080并监听;端口占用或权限不足(1–1023端口需root)将抛出bindexception;设为0则自动分配临时端口;显式bind()更灵活,支持地址限定、端口复用等;backlog指定已完成握手但未accept的连接队列长度,默认50。

直接用 ServerSocket 构造方法绑定端口最常用,但要注意底层行为和常见陷阱。
构造时绑定是最简洁的方式
写法如:new ServerSocket(8080)。这行代码会立即尝试将服务绑定到本机所有网卡的 8080 端口(即 0.0.0.0:8080),并开始监听。
- 如果端口已被占用,会立刻抛出 BindException(属于
IOException),错误信息类似Address already in use - 若指定端口为 1–1023,非 root/Admin 权限下会因权限不足而失败
- 端口号设为 0,系统会自动分配一个可用临时端口,适合需要动态端口的场景(如测试)
显式调用 bind() 方法更灵活
适用于需控制绑定地址、复用端口或延迟绑定的场景:
- 先创建未绑定实例:
ServerSocket ss = new ServerSocket() - 设置端口复用(避免
TIME_WAIT占用):ss.setReuseAddress(true) - 构造地址对象,例如只允许本地访问:
InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 8080) - 执行绑定:
ss.bind(addr)
这种方式能明确区分“创建 socket”和“绑定资源”两个阶段,便于异常分类处理和配置化管理。
绑定后必须用 accept() 进入监听循环
accept() 是阻塞方法,它不主动轮询,而是等待操作系统通知有已完成三次握手的连接就绪。
- 每次调用返回一个
Socket对象,代表与单个客户端的专属通信通道 - 若想优雅关闭,不能只靠
Thread.interrupt();必须在关闭逻辑中先调用ss.close(),它会让阻塞中的accept()立即抛出SocketException: Socket closed - 建议在循环中加判断:
if (ss.isClosed()) break;,防止 close 后继续调用 accept
backlog 参数影响连接排队能力
构造时可指定:new ServerSocket(8080, 100)。这个 100 不是最大并发数,而是内核中“已完成握手、等待你调用 accept() 取走”的连接队列长度。
- 默认值通常为 50,高并发短连接场景建议设为 100–200
- 超过 backlog 的新连接会被内核直接拒绝(客户端收到 RST 包),不是等待或超时
- 该值受系统限制(如 Linux 的
net.core.somaxconn),设得过大无实际效果
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











