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

Java通过TCP向C#发送整数时接收字节数组为空问题

Java TCP发送数据到C#接收失败问题

问题现象

通过TCP从Java程序向C#程序传输List<List<String>>数据,先发送JSON序列化后的数据长度(整数),再发送数据本身,但C#端接收的字节数组始终为空,改用BinaryReader读取整数长度结果仍为0。

双方相关代码

Java发送代码

public void SendData(List<List<String>> tooltips){
    try {
        Gson gson = new Gson();
        String jsonData = gson.toJson(tooltips);

        byte[] dataBytes = jsonData.getBytes(StandardCharsets.UTF_8);
        int totalBytes = dataBytes.length;

        DataOutputStream dos = new DataOutputStream(this.outputStream);
        dos.writeInt(totalBytes);
        dos.flush();

        // Send the data using the output stream
        this.outputStream.write(dataBytes);
        this.outputStream.flush();
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
}

Java连接代码

public SocketSender(String serverAddress, int serverPort) {
    this.serverAddress = serverAddress;
    this.serverPort = serverPort;
    try {
        this.socket = new Socket(this.serverAddress, this.serverPort);
        this.outputStream = this.socket.getOutputStream();
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
}

C#接收代码

public static List<List<string>> ReceiveListOfLists(TcpClient client)
{
    try
    {
        NetworkStream stream = client.GetStream();

        byte[] lengthBuffer = new byte[4];
        stream.Read(lengthBuffer, 0, lengthBuffer.Length);
        int dataLength = BitConverter.ToInt32(lengthBuffer, 0);

        // Read the data bytes
        byte[] dataBytes = new byte[dataLength];
        int bytesRead = 0;
        while (bytesRead < dataLength)
        {
            bytesRead += stream.Read(dataBytes, bytesRead, dataLength - bytesRead);
        }

        var jsonData = Encoding.UTF8.GetString(dataBytes);

        // Deserialize the JSON data into a List of Lists of strings
        var tooltips = JsonConvert.DeserializeObject<List<List<string>>>(jsonData);
        return tooltips;
    }
    catch (Exception e)
    {
        throw;
    }
}

C#连接代码

public class SocketManager
{
    private Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    private TcpListener tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 5020);
    private TcpClient client;
    public SocketManager() 
    {
        tcpListener.Start();
        client = tcpListener.AcceptTcpClient();
    }
    public List<List<string>> GetListOfStringList()
    {           
        return SocketReceiver.ReceiveListOfLists(client);
    }
}

问题原因

核心问题是字节序不匹配:Java的DataOutputStream.writeInt()默认采用大端字节序(Big-Endian),而C#的BitConverter.ToInt32()和BinaryReader.ReadInt32()默认采用小端字节序(Little-Endian),导致读取的长度值完全错误,后续读取数据自然失败。

另外,NetworkStream.Read()方法不一定会一次性读取到指定长度的字节,原代码未处理这种情况,可能导致长度读取不完整。

解决方法

1. 统一字节序

方案一:C#端转换字节序

修改C#读取长度的逻辑,将大端字节数组转为小端:

byte[] lengthBuffer = new byte[4];
int bytesRead = 0;
// 确保读取完整的4字节长度
while (bytesRead < 4)
{
    int read = stream.Read(lengthBuffer, bytesRead, 4 - bytesRead);
    if (read == 0) throw new IOException("连接断开");
    bytesRead += read;
}
// 反转字节数组,大端转小端
Array.Reverse(lengthBuffer);
int dataLength = BitConverter.ToInt32(lengthBuffer, 0);

方案二:Java端用小端发送长度

如果不想修改C#代码,Java端手动按小端字节序写入整数:

// 替换dos.writeInt(totalBytes);
byte[] lenBytes = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(totalBytes).array();
this.outputStream.write(lenBytes);
this.outputStream.flush();

2. 确保完整读取数据

无论是长度还是内容,都要通过循环确保读取到指定长度的字节,避免因TCP流的分段特性导致读取不完整。

修正后的完整C#接收代码

public static List<List<string>> ReceiveListOfLists(TcpClient client)
{
    try
    {
        NetworkStream stream = client.GetStream();

        // 读取完整的4字节长度
        byte[] lengthBuffer = new byte[4];
        int bytesRead = 0;
        while (bytesRead < 4)
        {
            int read = stream.Read(lengthBuffer, bytesRead, 4 - bytesRead);
            if (read == 0) throw new IOException("读取长度时连接断开");
            bytesRead += read;
        }
        // 转换大端字节序到小端
        Array.Reverse(lengthBuffer);
        int dataLength = BitConverter.ToInt32(lengthBuffer, 0);

        // 读取完整的数据内容
        byte[] dataBytes = new byte[dataLength];
        bytesRead = 0;
        while (bytesRead < dataLength)
        {
            int read = stream.Read(dataBytes, bytesRead, dataLength - bytesRead);
            if (read == 0) throw new IOException("读取数据时连接断开");
            bytesRead += read;
        }

        var jsonData = Encoding.UTF8.GetString(dataBytes);
        return JsonConvert.DeserializeObject<List<List<string>>>(jsonData);
    }
    catch (Exception e)
    {
        throw;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 15:53:09