《Java 网络编程基础》3.1 Socket 与 ServerSocket 基本用法
从 linkd 的最小阻塞 Echo 入口出发,拆开 ServerSocket 的 bind、listen、accept 与 Socket 的读写阻塞点,用本机实测说明 backlog、SO_REUSEADDR 与 TIME_WAIT 重绑行为,给出可停止的 Echo 服务器、半包边界和 netstat 诊断命令。
tag
从 linkd 的最小阻塞 Echo 入口出发,拆开 ServerSocket 的 bind、listen、accept 与 Socket 的读写阻塞点,用本机实测说明 backlog、SO_REUSEADDR 与 TIME_WAIT 重绑行为,给出可停止的 Echo 服务器、半包边界和 netstat 诊断命令。
InetAddress 解析可能返回多个地址,localhost 同时是 127.0.0.1 和 ::1。本节观察 getAllByName、IPv4/IPv6 回环、端口 0 的临时端口分配、重复绑定的 BindException 原文,以及 lo0 MTU 16384 与 en0 MTU 1500,并用 netstat/lsof 验证,最后落到 LinkdMain 的绑定日志。
UDP 一次 send 就是一条消息,但消息可能丢、可能被截断。本节用 DatagramSocket/DatagramPacket 实测数据报边界、100 字节缓冲接收 2000 字节报文时的静默截断、70000 字节报文的 Message too long,以及 4096 字节接收缓冲下 5000 个包只收到 3 个的丢包结果,并给出 linkd 指标上报的 UDP 边界。
linkd 的 HTTP 响应在 loopback 上被拆成多次 read。本节用最小程序观察三次握手在 Java 里的可见时刻、两次 write 被合并或拆开的真实输出、Nagle 与 setTcpNoDelay 的测量,以及 SO_LINGER(0) 触发 RST 和 TIME_WAIT 的 netstat 证据,最后落到 Connection 与 FrameDecoder 的边界处理。
把 linkd 拆成 core、http、ws、app 四个 Maven 模块,固定 JDK 25.0.5 与 9090/8080 端口约定;给出 JAVA_HOME 设置、父 POM、启动与 curl/lsof/netstat 验证步骤,并记录 macOS 没有 ss/epoll 时的替代诊断命令。
阻塞 Echo 与非阻塞 Selector Echo 各跑一遍,用线程栈、read 返回值和事件日志对比两种模型;再拆开 BIO、NIO、AIO 与 Reactor 的边界,说明 linkd 为什么用单线程事件循环加业务线程池,而不是给每个连接开一个线程。
一次 curl 请求打到 127.0.0.1:9090/healthz,中间经过内核监听队列、收发缓冲区、Selector 就绪事件、业务线程和响应写回。本节用 curl -v、lsof、netstat 与本机服务日志把这条路径逐层标出来,并说明 linkd 的 EventLoop、Handler 和 Connection 分别落在哪一层。