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

时间:2014-12-03 11:58:35

标签: java python sockets

我有一个python服务器正在监听java客户端。

我想从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 

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

1 个答案:

答案 0 :(得分:1)

您的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兼容,但可能并非总是如此。最好使用诸如http://www.json.org/java/index.html之类的Java JSON库来正确使用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]])