Java服务端读取Python客户端数据抛出java.io.EOFException如何解决
问题根因
你遇到的java.io.EOFException异常是Java的DataInputStream.readUTF()方法的特殊协议要求和Python发送的字节格式不匹配导致的:
- Java的
writeUTF()/readUTF()使用自定义的UTF传输协议:会先写入2个字节的无符号整数,标识后续字符串内容的字节长度,之后才是字符串对应的UTF-8字节序列 - 你的Python客户端直接发送了原始字符串编码后的字节,没有前面的2字节长度头,Java的
readUTF()读取时会先尝试读取2字节长度值,要么读不到足够数据,要么长度值错误,读到流末尾还没拿到符合格式的内容就会抛出EOF异常。
同时你当前的Python代码接收Java发送的writeUTF内容时,直接调用decode()会出现开头乱码的问题,因为Java发的内容前2位是长度标识,不是有效字符串内容。
解决方案
方案1:修改Python客户端,适配Java的readUTF协议
按照Java的自定义UTF传输格式组装发送内容,同时处理接收逻辑避免乱码:
import socket import struct s = socket.socket() host = socket.gethostname() port = 6000 s.connect((host, port)) message = s.recv(1024) # 先读取前2字节的长度标识,再读取对应长度的有效内容 utf_len = struct.unpack('>H', message[:2])[0] print(message[2:2+utf_len].decode()) # 发送时按Java协议组装:先加2字节大端序的长度,再加实际字符串字节 send_content = "Hello Server!".encode() send_data = struct.pack('>H', len(send_content)) + send_content s.send(send_data) s.close()
方案2:修改Java服务端,直接读取原始字节转字符串
如果不想改动Python客户端,可以把Java端的读写逻辑改为不使用readUTF/writeUTF,直接读写原始UTF-8字节:
import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.nio.charset.StandardCharsets; public class JavaFile { public static void main(String[] args){ try{ ServerSocket serversocket = new ServerSocket(6000); Socket socket = serversocket.accept(); InputStream input = socket.getInputStream(); OutputStream output = socket.getOutputStream(); output.write("Hello Client!".getBytes(StandardCharsets.UTF_8)); // 直接读取字节后转字符串 byte[] buffer = new byte[1024]; int len = input.read(buffer); String s = new String(buffer, 0, len, StandardCharsets.UTF_8); System.out.println(s); serversocket.close(); } catch(Exception e){ System.out.println(e); } } }
内容的提问来源于stack exchange,提问作者MichaPehlivan
相关产品推荐
相关产品推荐

