我想通过网络传输double []类型,然后以某种方式将其转移回接收方的double []。我不完全确定如何做到这一点。我试图将收到的String转换为char [],然后将所有字符解析为double []。然而,这不起作用,双倍有不同的数据。我需要这样做才能为opencv制作网络协议,以便轻松地传输Mat。
这就是数据的发送方式:
private void send_info(int row,int col, double[] data) {
//Convert data to String, separated by : to indicate change
//char[] sendit = data.toString().toCharArray();
out.println("INF:ROW:"+row+":COL"+":"+col+":"+data);
}
这就是它的收到方式:
private void setInfo(String input) {
input = input.trim();
input=input.replace("INF:","");
String inputs[] = input.split(":");
System.out.println(inputs[1]);
int row = Integer.parseInt(inputs[1]);
int col = Integer.parseInt(inputs[3]);
//double[] data = magic(inputs[4]);
// What I need ^
frame.put(row,col,data);
}
答案 0 :(得分:3)
根本不要转换它们。浪费时间和空间。直接做吧。发送double[] doubles
:
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
dos.writeInt(doubles.length); // send the array length
for (d : doubles)
{
dos.writeDouble(d);
}
dos.flush();
阅读:
DataInputStream din = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
double[] doubles = new double[dis.readInt()];
for (int i = i; i < doubles.length; i++)
{
doubles[i] = dis.readDouble();
}
或者您可以使用ObjectOutputStream.writeObject()
和ObjectInputStream.readObject()
一次写入和读取整个数组。或者你可以使用NIO和DoubleBuffer
:left作为读者的练习。
答案 1 :(得分:2)
作为EJP’s answer的附录,这里是一个NIO解决方案:
try(SocketChannel ch=SocketChannel.open(
new InetSocketAddress(InetAddress.getLocalHost(), 12345))) {
ByteBuffer buf=ByteBuffer.allocateDirect(doubles.length*Double.BYTES+Integer.BYTES);
buf.putInt(doubles.length).asDoubleBuffer().put(doubles);
buf.clear();
while(buf.hasRemaining()) ch.write(buf);
}
final int DEFAULT_BUFFER_SIZE = 4096;
try(ServerSocketChannel ss=ServerSocketChannel.open()
.bind(new InetSocketAddress(InetAddress.getLocalHost(), 12345));
SocketChannel ch=ss.accept()) {
ByteBuffer bb=ByteBuffer.allocateDirect(DEFAULT_BUFFER_SIZE);
bb.limit(Integer.BYTES);
while(bb.hasRemaining()) if(ch.read(bb)<0) throw new EOFException();
bb.flip();
int size=bb.getInt(), byteSize=size*Double.BYTES;
if(bb.capacity()<byteSize) bb=ByteBuffer.allocateDirect(byteSize);
else bb.clear().limit(byteSize);
while(bb.hasRemaining()) if(ch.read(bb)<0) throw new EOFException();
double[] doubles=new double[size];
bb.flip();
bb.asDoubleBuffer().get(doubles);
return doubles;
}
很明显缓冲区管理在接收端变得更复杂,因为双阵列长度是事先未知的。
如果我们想减少传输次数,即仅针对前四个字节避免不同的I / O操作,则该方法会变得更加复杂:
final int DEFAULT_BUFFER_SIZE = 4096;
try(ServerSocketChannel ss=ServerSocketChannel.open()
.bind(new InetSocketAddress(InetAddress.getLocalHost(), 12345));
SocketChannel ch=ss.accept()) {
ByteBuffer bb=ByteBuffer.allocateDirect(DEFAULT_BUFFER_SIZE);
while(bb.position()<4) if(ch.read(bb)<0) throw new EOFException();
bb.flip();
int size=bb.getInt(), byteSize=size*Double.BYTES;
if(bb.remaining()<byteSize) {
if(bb.capacity()<byteSize) bb=ByteBuffer.allocateDirect(byteSize).put(bb);
else bb.compact().limit(byteSize);
while(bb.hasRemaining()) if(ch.read(bb)<0) throw new EOFException();
bb.flip();
}
else bb.limit(bb.position()+byteSize);
double[] doubles=new double[size];
bb.asDoubleBuffer().get(doubles);
return doubles;
}
但请注意,该格式与EJP’s solution中使用DataOutputStream
创建的格式相同,因此您可以合并,例如NIO使用旧的I / O接收代码发送代码......