You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java客户端调用writeInt发整数到Python Socket服务端始终收到0的问题

异常行为原因分析

1. Java输出流未刷新导致数据未完全发送

Java的DataOutputStream默认自带内存缓冲,调用writeInt()后数据只是写入了本地进程的缓冲区,没有直接发送到网络链路。你当前代码没有调用flush()或者关闭流的操作,只有少量残留数据被发送,这是你拿到的num只有1个0字节的直接原因。

2. TCP流协议无固定报文边界

Python的con.recv(4)的参数4仅代表单次调用最多接收4字节,不保证凑齐4字节才返回。只要内核Socket缓冲区中有可读数据,哪怕只有1字节,recv都会立即返回。你测试需要调用4次recv才能凑齐4字节,就是TCP流协议的固有特性导致的。

为什么writeUTF可以单次接收1024字节?

writeUTF会先对字符串做编码转换,写入的数据量通常远大于4字节,触发了DataOutputStream的自动刷新阈值,缓冲区的数据被直接发送到网络,内核缓冲区中一次性就有了完整的报文内容,所以单次recv就能拿到更多数据。

修复方案
  • Java端新增缓冲刷新逻辑,确保所有数据被发出
Socket s = new Socket("localhost", 9999); // 建议使用1024以上的非保留端口,避免系统占用
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
dos.writeInt(2);
dos.flush(); // 强制刷新缓冲,将数据推送到网络
// 后续无数据传输可直接关闭流:dos.close(); s.close();
  • Python端封装固定长度读取逻辑,避免数据接收不完整
import socket

def recv_exact(conn, byte_len):
    buf = b''
    while len(buf) < byte_len:
        chunk = conn.recv(byte_len - len(buf))
        if not chunk:
            raise ConnectionResetError("连接已断开,无法读取完整数据")
        buf += chunk
    return buf

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("localhost", 9999))
s.listen(5)
con, addr = s.accept()
num_bytes = recv_exact(con, 4)
print(int.from_bytes(num_bytes, byteorder='big'))

内容的提问来源于stack exchange,提问作者LOLs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 08:15:04