通过套接字将固定长度的数组从Java发送到python - java

我有一个正在侦听Java客户端的python服务器。

我想将数组从java发送到python,并通过将数组发送回来进行响应。

我正在像这样从python监听:

INPUT_SPEC = {'rows': 5, 'columns': 2, 'dtype': np.dtype('float32')}
OUTPUT_SPEC = {'rows': 1, 'columns': 1, 'dtype': np.dtype('float32')}

while True:
    # Wait for a connection
    print >>sys.stderr, 'waiting for a connection'
    connection, client_address = sock.accept()
    nbytes = INPUT_SPEC['rows'] * INPUT_SPEC['columns'] * INPUT_SPEC['dtype'].itemsize
    try:
        print >>sys.stderr, 'connection from', client_address
data = connection.recv(nbytes)



 a = np.fromstring(data, dtype = INPUT_SPEC['dtype']).reshape((INPUT_SPEC['rows'], INPUT_SPEC['columns']))
    result = np.array(mysum(a), dtype = OUTPUT_SPEC['dtype']).reshape((OUTPUT_SPEC['rows'], OUTPUT_SPEC['columns']))
    print >>sys.stderr, 'sending data back to the client: {0}'.format(result)
    connection.sendall(result.tobytes())



except Exception as e:
    print(e)
    connection.close()
finally:
    # Clean up the connection
    connection.close()

我是这样从Java发送的:

String hostName = "localhost";
        int portNumber = 10000;

        try (

                //open a socket
                Socket clientSocket = new Socket(hostName, portNumber);


                BufferedReader in =  new BufferedReader( new InputStreamReader(clientSocket.getInputStream()));
                PrintWriter out =  new PrintWriter(clientSocket.getOutputStream(), true);

        ) {

            System.out.println("Connected");

            Double[][] test2 =   new Double[5][2];
            test2[1][1]= 0.1;
            test2[1][0]= 0.2;
            test2[2][1]= 0.2;
            test2[2][0]= 0.2;
            test2[3][1]= 0.1;
            test2[3][0]= 0.2;
            test2[4][1]= 0.2;
            test2[4][0]= 0.2;
            test2[0][1]= 0.2;
            test2[0][0]= 0.2;



            out.println(test2);

            String response;
            while ((response = in.readLine()) != null)
            {
                System.out.println( response );
            }


        }

我收到的错误消息是:

string size must be a multiple of element size 

因此,我不能很好地定义发送的数据。有什么建议么?

参考方案

您的Java代码正在通过套接字发送此代码:

[[Ljava.lang.Double;@3be74fe9

如果您打印数组变量,这基本上就是您得到的。您可以尝试使用test2java.util.Arrays.deepToString(test2)转换为字符串,这将产生test2的字符串表示形式:

[[0.2, 0.2], [0.2, 0.1], [0.2, 0.2], [0.2, 0.1], [0.2, 0.2]]

然后将其发送给Python,但是,您必须将其解析为一个numpy数组,它不能很好地适应客户端软件(例如另一种语言)中的潜在更改。

您应该考虑一种更通用的使用JSON之类的序列化数据的方法。这将避免诸如数据类型大小,字节序,格式,顺序等陷阱。这也将使其在Python中反序列化变得微不足道,并且您无需在Python中确定数组的尺寸,例如

import json
import numpy as np
data = connection.recv(nbytes)    # N.B. you may need multiple reads to get all of the data.
a = np.array(json.loads(data))

碰巧的是,在这种情况下,deepToString(test2)的输出与JSON兼容,但并非总是如此。最好使用Java JSON库(例如http://www.json.org/java/index.html)来正确使用JSON。您的Java代码为:

import org.json.*;
.
.
.
Double[][] test2 = new Double[5][2];
test2[1][1]= 0.1;
test2[1][0]= 0.2;
test2[2][1]= 0.2;
test2[2][0]= 0.2;
test2[3][1]= 0.1;
test2[3][0]= 0.2;
test2[4][1]= 0.2;
test2[4][0]= 0.2;
test2[0][1]= 0.2;
test2[0][0]= 0.2;

out.println(new JSONArray(test2).toString());

Python将接收JSON字符串[[0.2,0.2],[0.2,0.1],[0.2,0.2],[0.2,0.1],[0.2,0.2]],然后可以通过np.array(json.loads(data))将其解析为:

array([[ 0.2,  0.2],
       [ 0.2,  0.1],
       [ 0.2,  0.2],
       [ 0.2,  0.1],
       [ 0.2,  0.2]])

Java-如何将此字符串转换为日期? - java

我从服务器收到此消息,我不明白T和Z的含义,2012-08-24T09:59:59Z将此字符串转换为Date对象的正确SimpleDateFormat模式是什么? java大神给出的解决方案 这是ISO 8601标准。您可以使用SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM…

Java:线程池如何将线程映射到可运行对象 - java

试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …

JAVA:字节码和二进制有什么区别? - java

java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

Java:BigInteger,如何通过OutputStream编写它 - java

我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…