Java:通过套接字向/从用 C 编码的程序发送/接收 int 数组

标签 java arrays sockets

我想将整个整数数组从 Java 发送到另一个用 C 编码的程序,反之亦然。

我已经阅读了 here我应该在 Java 中使用 short 数组,而在 C 程序中使用普通的 int 数组。

作为 Java 的新手,我仍然不太确定如何正确地执行此操作。下面是我的代码:

package tcpcomm;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import datatypes.Message;

public class PCClient {

    public static final String C_ADDRESS = "192.168.1.1";
    public static final int C_PORT = 8888;

    private static PCClient _instance;
    private Socket _clientSocket;
        private ByteArrayOutputStream _toCProgram;
        private ByteArrayInputStream _fromCProgram;

    private PCClient() {

    }

    public static PCClient getInstance() {
        if (_instance == null) {
            _instance = new PCClient();
        }
        return _instance;
    }

    public static void main (String[] args) throws UnknownHostException, IOException {
        int msg[] = {Message.READ_SENSOR_VALUES};
        ByteArrayOutputStream out = new ByteArrayOutputStream();

    PCClient pcClient = PCClient.getInstance();
    pcClient.setUpConnection(C_ADDRESS, C_PORT);
    System.out.println("C program successfully connected");
    while (true) {
        pcClient.sendMessage(out, msg);
        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
        int[] msgReceived = pcClient.readMessage(in);
      } 
    }

    public void setUpConnection (String IPAddress, int portNumber) throws UnknownHostException, IOException{
        _clientSocket = new Socket(C_ADDRESS, C_PORT);
        _toCProgram = new PrintWriter(_clientSocket.getOutputStream());
        _fromCProgram = new Scanner(_clientSocket.getInputStream());
    }

    public void closeConnection() throws IOException {
        if (!_clientSocket.isClosed()) {
            _clientSocket.close();
        }
    }

    public void sendMessage(OutputStream out, int[] msg) throws IOException {
        int count = 0;
        DataOutputStream dataOut = new DataOutputStream(out);
        dataOut.writeInt(msg.length);
        System.out.println("Message sent: ");
        for (int e : msg) {
            dataOut.writeInt(e);
            System.out.print(e + " ");
            if(count % 2 == 1)
                System.out.print("\n");
            count++;
        }
        dataOut.flush();
    }

    public int[] readMessage(InputStream in) throws IOException {
        int count = 0;
        DataInputStream dataIn = new DataInputStream(in);
        int[] msg = new int[dataIn.readInt()];
        System.out.println("Message received: ");
        for (int i = 0; i < msg.length; ++i) {
            msg[i] = dataIn.readInt();
            System.out.print(msg[i] + " ");
            if(count % 2 == 1)
                System.out.print("\n");
            count++;
        }
        return msg;
    }
}

感谢任何有关如何更正代码的指导!!

我需要将流从 bytearray 更改为 intarray 吗?听起来转换很多..(基于我可以在这里找到的答案)

最佳答案

回答您的问题:不,您不需要将流从byte 更改为int。 Java 中 I/O 流的部分特性是它们是基于 byte 的。因此,当您想将 int 写入流时,您需要将其拆分为 byte 元素并分别写入。

Java 使用 4 字节有符号整数,您无法更改它。对于您的对应物(您的 C 程序),您需要确保它使用等效类型,例如 stdint.h 中的 int32_t。这可以被视为您的“协议(protocol)”的一部分。

Java 已经提供了通过 java.io.DataInputStream 从流中读取和写入 intlong 等值的方法和 java.io.DataOutputStream。重要的是要记住 DataOutputStream#writeInt(int)int 的四个字节从高到低写入。这叫做 Endianness ,但我很确定你已经知道了。这也可以被视为您的“协议(protocol)”的另一部分。

最后,在传输结构时,正在读取的端点必须知道它必须读取多少。对于固定大小的结构,双方(客户端和服务器)都已经知道大小,但数组可以变化。所以在发送的时候,你需要告诉你的对方你要发送多少。如果是数组,则非常简单,只需先发送数组长度(只是另一个 int)。这可以被视为您的“协议(protocol)”的另一部分。

我已经编写了一个示例,用于在流中写入和读取 int 数组。

package com.acme;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;

public class SendAndReceive {

    public static void main(String[] args) throws IOException {
        int[] ints = new int[] {Integer.MIN_VALUE, -1, 0, 1, Integer.MAX_VALUE};

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        writeInts(out, ints);
        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
        int[] results = readInts(in);

        if (!Arrays.equals(ints, results)) System.out.println("Damn!");
        else System.out.println("Aaall's well!");
    }

    private static void writeInts(OutputStream out, int[] ints) throws IOException {
        DataOutputStream dataOut = new DataOutputStream(out);
        dataOut.writeInt(ints.length);
        for (int e : ints) dataOut.writeInt(e);
        dataOut.flush();
    }

    private static int[] readInts(InputStream in) throws IOException {
        DataInputStream dataIn = new DataInputStream(in);
        int[] ints = new int[dataIn.readInt()];
        for (int i = 0; i < ints.length; ++i) ints[i] = dataIn.readInt();
        return ints;
    }
}

您需要做的就是使用方法 writeInts(OutputStream, int[])readInts(InputStream) 并用您的套接字流调用它们。

出于演示目的,我没有实现 C 程序,因为没有标准的套接字实现(虽然有 Boost 库,但它不是标准的,也不是 C 而是 C++)。

玩得开心!

关于Java:通过套接字向/从用 C 编码的程序发送/接收 int 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35527516/

相关文章:

java - 用 Java 开发游戏的最佳软件包是什么?

php - 如何将此字符串反序列化为键=>值对的PHP数组?

java - android上的socket,每隔一个请求就会消失

java - 选择查询未能找到记录

java - Jade 无法创建代理 MyAgent

python - 二进制文件转python整数列表

c++ - C++中数组的QVector

java - 丢失的套接字消息

python - Python UDP套接字在recvfrom()上引发立即错误

java - 如何过滤JTextField中的某些字符