我想将整个整数数组从 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
从流中读取和写入 int
、long
等值的方法和 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/