4

Javaクライアントからデータを受信する必要がある単純なpythontcpサーバーSocketServerクラスを使用しています)に問題があります。

ここにサーバー側のコードがあります:

class ServerRequestHandler(SocketServer.BaseRequestHandler):
    [...]
    def handle(self):
        requestCode = struct.unpack('>i', self.request.recv(4))[0]
        [...]
    [...]

ここにクライアントがあります:

addr = InetAddress.getByName(hostname);
SocketAddress sockaddr = new InetSocketAddress(addr, port);
clientSocket = new Socket();
clientSocket.connect(sockaddr, timeoutMs);
clientSocketDataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
int   requestCode = 1;
clientSocketDataOutputStream.writeInt(requestCode);
clientSocketDataOutputStream.flush();

Pythonサーバーを起動してから、サーバーに整数を送信する必要のあるクライアントを実行しようとします。

recv(4)サーバー側では、関数が4バイトを読み取らないため、Pythonは例外を発生させ、1バイトのみを返します。

私のJavaクライアントは実際には4バイトを正しく送信しますが、recv(1)4回呼び出そうとすると、4バイトを正しく読み取ります。

Javaクライアントと同じ操作を実行するPythonクライアントを作成しようとしましたが、この場合、サーバーは正常にrecv(4)機能します。

この問題を解決する方法は?buffered reader functionソケットからバイトごとに読み取る単純なPythonを実装しようと思いましたが、よりスマートなソリューションが存在すると確信しています。

4

3 に答える 3

5

recvは4バイトを読み取る必要はなく、最大4バイトまでそこにあるものをすべて取得します。あなたが言ったように、あなたはrecv(1)を4回呼び出すことができるので。あなたはこれを行うことができます

def recvall(sock, size):
    msg = ''
    while len(msg) < size:
        part = sock.recv(size-len(msg))
        if part == '': 
            break # the connection is closed
        msg += part
    return msg

これは、バイトが受信されるまで繰り返し呼び出さrecvれます。ソケットが閉じている場合は、閉じる前にあったものがすべて返されますsocksizepart == ''

だから変更

requestCode = struct.unpack('>i', self.request.recv(4))[0]

requestCode = struct.unpack('>i', recvall(self.request, 4))[0]

私はrecvall物事をよりきれいにするためにあなたのクラスのメソッドを作ることを提案します。


これは、ここで定義されているセーフソケットクラスのメソッドの変更です:http://docs.python.org/howto/sockets.html

于 2012-08-08T19:35:27.470 に答える
0

recv(4)は最大4バイトを読み取ります。ドキュメントを参照してください:http://docs.python.org/library/socket.html。単純なバッファ付きリーダー関数を作成することは、ここでは完全に受け入れられる解決策だと思います。

于 2012-08-08T19:33:42.670 に答える
0

多分あなたはioモジュールから何かを使うことができますか?たとえば、BufferedRWPair 。

于 2012-08-08T19:35:28.050 に答える