【问题标题】:Receiving python json through sockets with java使用java通过套接字接收python json
【发布时间】:2016-10-22 08:22:24
【问题描述】:

我一直在关注多个教程,通过套接字将 java 代码连接到 python。

使用 json 数组从 java 发送到 python 效果很好。但是,我似乎无法用 java 接收东西。我真的不明白应该如何进行听力。现在我只听一个 15 秒的 while 循环(python 应该在收到输入后立即发送),但我觉得我做错了什么。也许有人有想法?

client.py:

import socket
import sys
import numpy as np
import json

# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Bind the socket to the port
server_address = ('localhost', 10004)
print >>sys.stderr, 'starting up on %s port %s' % server_address
sock.bind(server_address)

# Listen for incoming connections
sock.listen(1)

def mysum(x):
    return np.sum(x)

while True:
    # Wait for a connection
    print >>sys.stderr, 'waiting for a connection'
    connection, client_address = sock.accept()
    infile = sock.makefile();

    try:
        print >>sys.stderr, 'connection from', client_address

        # Receive the data in small chunks and retransmit it
        data = b''
        while True:
             new_data = connection.recv(16)
             if new_data:
                 # connection.sendall(data)
                 data += new_data
             else:
                 data += new_data[:]
                 print >>sys.stderr, 'no more data from', client_address
                 break
        data= data.strip('\n');
        print("data well received!: ")
        print(data,)
        print(np.array(json.loads(data)));

        #send a new array back

        sendArray =  np.array( [ (1.5,2,3), (4,5,6) ] );
        print("Preparing to send this:");
        print(sendArray);
        connection.send(json.dumps(sendArray.tolist()));

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

server.java:

import java.io.*;
import java.net.Socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

import org.json.*;

import java.net.ServerSocket;

public class SocketTest {

    public static void main(String[] args) throws IOException {


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

        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;


            System.out.println("A");
            out.println(new JSONArray(test2).toString());
            System.out.println("B");


            long t = System.currentTimeMillis();
            long end = t + 15000;


            while (System.currentTimeMillis() < end) {
                String response;
                while ((response = in.readLine()) != null) {
                    System.out.println("receiving");
                    System.out.println( response );

                }


            }


            //listen for input continuously? 


            //clientSocket.close();
        } catch (JSONException e) {
            e.printStackTrace();
        }


    }


}

python 的输出是:

data well received!: 
('[[0.2,0.2],[0.2,0.1],[0.2,0.2],[0.2,0.1],[0.2,0.2]]',)
[[ 0.2  0.2]
 [ 0.2  0.1]
 [ 0.2  0.2]
 [ 0.2  0.1]
 [ 0.2  0.2]]
Preparing to send this:
[[ 1.5  2.   3. ]
 [ 4.   5.   6. ]]
closed
waiting for a connection
connection from ('127.0.0.1', 40074)

java 输出:

A
B

问题在于 sendArray = np.array( [ (1.5,2,3), (4,5,6) ] ); java从来没有收到过。我觉得我错过了一些简单的东西让它听...感谢您的帮助。

【问题讨论】:

  • 如果你正在使用资源尝试为什么要关闭clientSocket?
  • 你是对的,对不起,当删除 close() 时它仍然有同样的问题。
  • 问:“Java”是Android,对吗?问:如果用集合代替数组会发生什么?
  • 不是安卓,只是java

标签: java python json sockets


【解决方案1】:

您的代码有多个问题。

1. Client.py 和 Server.java 都在等待接收数据,导致死锁。

Client.py 在 True 时被阻塞,继续等待新数据。
Server.java已经发送了JSONArray(test2).toString(),长度为51。然后一直在in.readLine()等待。

How to identify end of InputStream in java。同样的想法也适用于 python。最好知道要读取多少字节。

更改:因为 JSONArray(test2).toString() 的长度为 51,所以你替换

    while True:
         new_data = connection.recv(16)
         if new_data:
             # connection.sendall(data)
             data += new_data
         else:
             data += new_data[:]
             print >>sys.stderr, 'no more data from', client_address
             break

 data = connection.recv(51)

2. Server.java 调用 in.readLine()。但是 Client.py 从不发送 '\n' 并过早关闭套接字。它会导致 in.readLine() 抛出异常。

更改:发送 '\n' 以便 Server.java 可以成功读取一行。

    connection.send(json.dumps(sendArray.tolist()));
    connection.send("\n");

3. Client.py 关闭套接字,导致无穷无尽的in.readLine() 抛出“Connection reset”异常。

更改:确保双方不再发送/接收数据,然后一起关闭套接字。

1&2更改后的代码。 (解决3需要更多的努力,这不是这个问题的重点):

public class Server {

  public static void main(String[] args) throws IOException {


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

    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;


      System.out.println("A");
      out.println(new JSONArray(test2).toString());
      System.out.println("B");


      long t = System.currentTimeMillis();
      long end = t + 15000;


      while (System.currentTimeMillis() < end) {
        String response;
        while ((response = in.readLine()) != null) {
          System.out.println("receiving");
          System.out.println( response );

        }
      }
      //listen for input continuously?
      //clientSocket.close();
    } catch (JSONException e) {
      e.printStackTrace();
    }
  }
}

Client.py 输出:

starting up on localhost port 10004
waiting for a connection
connection from ('127.0.0.1', 53388)
data well received!: 
('[[0.2,0.2],[0.2,0.1],[0.2,0.2],[0.2,0.1],[0.2,0.2]]',)
[[ 0.2  0.2]
 [ 0.2  0.1]
 [ 0.2  0.2]
 [ 0.2  0.1]
 [ 0.2  0.2]]
Preparing to send this:
[[ 1.5  2.   3. ]
 [ 4.   5.   6. ]]
closed

Server.java 输出:

Connected
A
B
receiving
[[1.5, 2.0, 3.0], [4.0, 5.0, 6.0]]
Exception in thread "main" java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:209)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)

【讨论】:

  • 谢谢。我没有收到错误,所以可能是我在发布时删除了太多代码。但我有个问题。我不知道我需要发送的长度或数组。基本上,java 将发送数组(大约 100 000 次),python 会以双精度回答。 (就像 java 正在调用一个远程函数)。
  • 如果客户端知道数据的长度,客户端先发送长度,然后发送数据。所以服务器会知道流何时结束。如果您不知道长度或者您知道客户端可能会提前结束流,一种选择是将您的数据包装到某个数据包中。然后你可以有一个特殊的数据包来指示EOF。一切都与协议有关。
  • 其实我觉得收货没问题。它只是在长度为 16 的数据包中接收它,并将其连接起来,直到没有更多新数据为止。它似乎只是发送数据。
【解决方案2】:

发生这种情况是因为您的 java 代码被阻塞了。看看 B 如何没有打印到您的日志中?这是因为它没有执行,因为这部分正在等待刷新命令:out.println(new JSONArray(test2).toString());。你需要做的是out.flush();,然后继续。

【讨论】:

  • B 打印在日志中。所以我认为这仍然是另一回事。
  • 也许你有竞争条件。如何让 python 代码等待 5 秒以确保您的 java 代码正在侦听。如果 python 代码总是以某种方式更快地执行并在 java 代码侦听之前发送数据,那将会很有趣。
猜你喜欢
  • 2017-02-25
  • 1970-01-01
  • 2014-03-25
  • 1970-01-01
  • 2016-12-08
  • 1970-01-01
  • 1970-01-01
  • 2020-12-21
  • 1970-01-01
相关资源
最近更新 更多