1

私が書いたソケットサーバーで、ソケットサーバーが使用するポートの1つでデータの送受信を停止するように見える問題が発生しました(他のポートはデータを正常に処理し続けます)。興味深いことに、1 分 (または最大で 1 時間程度) 待機した後、socketserver は観察可能な介入なしでメッセージの送受信を再開します。

私はEventletソケットフレームワーク、python 2.7を使用しています。すべてがubuntu awsインスタンスで実行され、外部アプリがソケットサーバーへの永続的な接続を開きます。

私が行ってきたいくつかの読書から、ソケットサーバーを正しく実装していないようです。http://docs.python.org/howto/sockets.htmlによると:

ソケットの基本的な真実: メッセージは、固定長 (yuck)、区切り記号 > > (肩をすくめる)、メッセージの長さを示す (はるかに良い)、または接続をシャットダウンして終了する必要があります。

ここで固定長メッセージを使用しているかどうかは完全にはわかりません (またはそうですか?)

これは私が自分のデータを受け取る方法です:

def socket_handler(sock, socket_type):
    logg(1,"socket_handler:initializing")
    while True:
        recv = sock.recv(1024)
        if not recv:
            logg(1,"didn't recieve anything")
            break
        if len(recv) > 5:
            logg(1,"socket handler: %s" % recv )
            plug_id, phone_sid, recv_json = parse_json(recv)
            send = 1 
            if "success" in recv_json and recv_json["success"] == "true" and socket_type == "plug":
                send = 0
            if send == 1:
                send_wrapper(sock, message_relayer(recv, socket_type))
        else:
            logg(2, 'socket_handler:Ignoring received input: ' + str(recv)  )
    logg(1,  'Closing socket handle: [%s]' % str(sock))
    sock.shutdown(socket.SHUT_RDWR)
    sock.close()

「sock」は、listener.accept() 関数によって返されるソケット オブジェクトです。

socket_handler 関数は次のように呼び出されます。

new_connection, address = listener.accept()
...<code omitted>...
pool.spawn_n(socket_handler, new_connection, socket_type)

私の実装は誰かに間違っているように見えますか? 基本的に固定長の会話プロトコルを実装していますか? 問題を調査したり、コードをより堅牢にするために何ができますか?

前もって感謝します、

T

4

1 に答える 1

2

サーバーで実際にクライアントから送信しているよりも多くのバイト(1024)を受信するように要求している場合は、バッファリング関連の問題が発生している可能性があります。

この問題を解決するために、通常行われることは、最初にメッセージの長さをエンコードし、次にメッセージ自体をエンコードすることです。このようにして、受信者は長さフィールド(既知のサイズ)を取得し、デコードされた長さに基づいてメッセージの残りの部分を読み取ることができます。

注:長さフィールドは通常、プロトコルで必要な長さのバイト数です。一部のプロトコルは4バイトで整列され、これに32ビットフィールドを使用しますが、1バイトまたは2バイトで十分であることがわかった場合は、それを使用できます。ここでのポイントは、クライアントとサーバーの両方がこのフィールドのサイズを知っているということです。

于 2012-01-09T15:11:27.640 に答える