为何直接使用OutputStream与PrintWriter的Socket数据发送行为不一致?
两段代码的核心差异及问题原因
核心差异
数据编码转换逻辑不同
第一段用PrintWriter(字符流)发送,需要先把原始字节数组转成String,再由PrintWriter将字符串按平台默认编码转回字节发送。这个二次转换过程会破坏原始字节的完整性——如果原始XML字节的编码和转换时用的编码不匹配,部分字节会被替换成占位符(比如�),直接打乱XML结构。
第二段直接用OutputStream(字节流)发送,完全保留原始字节数组的内容,没有任何编码转换。发送的有效数据范围不同
如果buffer是ByteBuffer类型,buffer.array()返回的是缓冲区的整个底层数组,包含了未被使用的填充字节(比如缓冲区容量1024,但实际只写入了500字节有效数据,剩下的524字节是默认的0值)。
- 第一段中,
new String(buffer.array())会把数组转成字符串,字符串遇到0字节会自动截断,最终PrintWriter只发送了有效数据部分; - 第二段直接发送整个数组,包括后面的大量空字节。
为什么出现不同的响应
- 第一段虽然XML结构被编码转换破坏,但服务器确实收到了完整的有效数据(被截断后的内容),能识别这是一个完整的请求,所以返回“未接收到正确XML”的解析错误;
- 第二段发送了包含大量空字节的数组,服务器的读取逻辑可能在等待特定长度的有效数据,或者无法从空字节中识别请求结束的信号,因此一直阻塞等待更多数据,没有返回任何响应。
另外还有一种常见场景:如果服务器是通过换行符(\r\n)判断请求结束,而packData生成的字节数组里没有这个结束符。第一段的编码转换可能意外生成了换行符,让服务器认为请求结束;而第二段没有结束符,服务器就一直等待。
内容的提问来源于stack exchange,提问作者Loading
相关产品推荐
相关产品推荐

