2016-06-20 8 views
2

私はソケットを介してPythonにJavaコードを接続するために複数のチュートリアルを続けてきました。python jsonからjavaでソケットを受け取る

javaからpythonへの送信は、json配列でうまくいきます。しかし、私はjavaで物事を受け取ることができないようです。聞き取りの仕方は分かりません。今私はちょうど15秒間のループで聞いています(入力を受け取るとすぐに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からの出力がされます。javaから

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) 

出力:

A 
B 

問題はsendArray = np.array([(1.5,2,3)、(4,5,6)])です。 Javaによって決して受信されません。私はそれを聞くために簡単な何かが欠けているように感じる...任意の助けをありがとう。

+0

リソースの試行を使用している場合、なぜあなたはclientSocketを終了しますか? –

+0

あなたは正しいです、申し訳ありませんが、close()を削除するときにも同じ問題があります。 – dorien

+0

Q:「Java」はAndroidですか、正しいですか? Q:配列の代わりにCollectionを置き換えるとどうなりますか? – paulsm4

答えて

1

あなたのコードには複数の問題があります。

1.デッドロックの原因となるClient.pyとServer.javaの両方がデータの受信を待機しています。

Client.pyはでブロックされていますが、Trueでブロックされ、新しいデータを待っています。
Server.javaは、長さが51のJSONArray(test2).toString()をに送信してから、in.readLine()で待機し続けます。

How to identify end of InputStream in javaを参照してください。同じ考え方がPythonで動作します。読み込むバイト数を知っている方がよいでしょう。

変更:in.readLineを呼び出して、あなたが

data = connection.recv(51) 

2. Server.javaで

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 

を置き換えるようJSONArray(TEST2).toString()は、長さ51を持っているので()。しかし、Client.pyは '\ n'を送信せず、あまりにも早くソケットを閉じました。それはin.readLine()例外をスローします。

変更: '\ n'を送信すると、Server.javaは正常に行を読み取ることができます。

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

3で無限の原因となるソケットを閉じるClient.py。readLine()は「接続リセット」例外をスローします。

変更点:データが送受信されないようにしてから、ソケットを閉じてください。

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 

サーバ1 & 2の変化(これは、3を解決するために多くの努力を必要とし、それがこの質問のポイントではありません)後

コード.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) 
+0

ありがとうございます。私はエラーを出さないので、投稿する際にコードをあまりにも多く削除している可能性があります。私はしかし、質問があります。私は長さや、私が送る必要がある配列を知らない。基本的には、Javaは配列(約100 000回)を送信するつもりです、Pythonは二重で答えます。 (javaがリモート関数を呼び出すように)。 – dorien

+0

クライアントがデータの長さを知っている場合、クライアントは最初に長さを送信してからデータを送信します。したがって、サーバーはストリームが終了するときを知ります。長さがわからない場合、またはクライアントがストリームを早期に終了する可能性があることがわかっている場合は、データをパケットにラップする方法があります。その後、EOFを示す特別なパケットを持つことができます。それはプロトコルに関するすべてです。 – waltersu

+0

実際、受信はうまく動作すると思います。長さ16のパケットで受信し、新しいデータがなくなるまで連結します。それはちょうどデータの送信と思われます。 – dorien

2

これは、Javaコードがブロックされているために発生しています。あなたのログにBがどのように印刷されていないかを見てください。これは、この部分がフラッシュコマンドを待っているために実行されないためです:out.println(new JSONArray(test2).toString());。あなたがする必要があるのはout.flush();です。

+0

Bがログに出力されます。だから私はそれがまだ別のものだと思う。 – dorien

+0

もう一度もう一度見てみましょう。編集のおかげで。 – limbo

+0

あなたは競争状態にあるかもしれません。 Pythonコードを5秒間待ち、Javaコードがリッスンしていることを確認してください。 Pythonコードがいつもより速く実行され、Javaコードがリスニングする前にデータを送信すると面白いでしょう。 – limbo

関連する問題