如何将用户输入的字符串转为字节数组写入Socket?
Socket消息无法发送问题排查与修复
问题根因
- 循环逻辑错误:你在循环外调用
r.readLine()阻塞读取了用户输入的第一行,但是循环判断条件添加了r.ready()校验。该方法仅在当前有可无阻塞读取的内容时返回true,如果用户输入完一行后没有立刻输入下一行,r.ready()直接返回false,循环体全程不会执行,写入逻辑根本没有运行。 - 未冲刷输出缓冲区:Socket的
OutputStream默认带有缓冲区,仅当缓冲区写满、主动调用flush()或者流关闭时,才会真正把数据发送到网络对端。仅调用write()方法时,数据会暂存在本地缓冲区,不会实际发出。 - 未匹配服务端读取规则:如果服务端使用
BufferedReader.readLine()读取消息,会一直阻塞直到收到换行符或者流关闭才会返回结果。你直接发送用户输入的字符串,默认不会携带换行符,会导致服务端认为消息未接收完成,不会处理该条数据。
修正后代码
import java.nio.charset.StandardCharsets; // ... 其余代码省略 BufferedReader r = new BufferedReader(new InputStreamReader(System.in)); // 提前获取输出流,无需每次循环重复获取 OutputStream outputStream = s.getOutputStream(); String newLine; // 移除r.ready()判断,readLine本身会阻塞等待用户输入 while ((newLine = r.readLine()) != null) { // 追加换行符匹配服务端按行读取逻辑,同时指定编码避免乱码 byte[] message = (newLine + System.lineSeparator()).getBytes(StandardCharsets.UTF_8); outputStream.write(message); // 手动冲刷缓冲区,立刻发送数据 outputStream.flush(); } // 业务结束后记得关闭流和Socket连接 outputStream.close(); s.close();
补充注意
如果服务端有自定义的消息协议(比如前4字节存储消息长度、固定长度消息头),需要按照服务端约定的格式组装数据后再发送,否则服务端依旧无法正常解析消息。
内容的提问来源于stack exchange,提问作者kim
相关产品推荐
相关产品推荐

