最简双向聊天程序需服务端监听单连接并双线程收发、客户端连接后同样双线程通信;双方用bufferedreader读、printwriter写,必须分离读写线程避免阻塞,printwriter开启autoflush,readline()返回null时断连退出。

用 ServerSocket 和 Socket 写一个最简双向聊天程序,核心在于:服务端监听连接、客户端发起连接、双方各自开线程读写、用 BufferedReader 和 PrintWriter 处理文本流。
服务端:监听 + 单客户会话
服务端只需处理一个客户端(简化版),启动后阻塞等待连接。一旦连上,就用两个线程分别收发消息——避免读写互相卡住。
- 创建
ServerSocket绑定端口(如 8080),调用accept()阻塞等待连接 - 获取客户端
Socket的输入输出流,包装成BufferedReader和PrintWriter - 另起一个线程持续读取客户端发来的消息(
readLine()),打印到控制台 - 主线程从控制台读取用户输入,通过
PrintWriter发送给客户端(记得flush())
客户端:连接 + 双向通信
客户端主动连接服务端 IP 和端口,连接成功后同样需要双线程:一个读服务端消息,一个发本地输入。
- 用
Socket("127.0.0.1", 8080)连接本地服务端;若跨机,把"127.0.0.1"换成服务端真实 IP - 同样包装输入输出流,注意
PrintWriter构造时传true开启自动 flush - 开子线程循环读取服务端发来的消息(
readLine()返回null表示断连) - 主线程读控制台输入,写入输出流并换行(
println()自带 \n)
关键细节:别卡在 IO 上
单线程串行读写会导致“你发我才能收,我发你才能收”,变成半双工。必须分离读写逻辑,否则一端不发,另一端就永远 readLine() 阻塞。
-
PrintWriter要设autoFlush = true,或每次写完手动flush() -
BufferedReader.readLine()遇到对方关闭连接会返回null,应据此退出读循环 - 双方都需在异常或断连时关闭自己的 socket 和流,避免资源泄漏
- 中文正常显示,前提是两端编码一致(默认系统编码,通常没问题)
运行效果与下一步
先启动服务端,再启动客户端,任意一端输入回车即发送,对方立即收到并显示。消息按行传递,支持中文和空格。
这个版本只支持一对一。想升级为多客户端,服务端需把每个 Socket 交给独立线程处理,并用集合管理所有连接;还可加入昵称、广播、私聊等逻辑。











