3

シンプルな UDP クライアントとサーバーを実装しようとしています。サーバーはメッセージを受信し、変換されたメッセージを返す必要があります。

サーバーの主なテクニックは、UDP メッセージをループでリッスンし、multiprocessing.Process着信メッセージごとに生成し、各Processインスタンス内で応答を送信することです。

class InputProcessor(Process):
    ...

    def run(self):
        output = self.process_input()
        self.sock.sendto(output, self.addr) # send a reply

if __name__ == "__main__":
    print "serving at %s:%s" % (UDP_IP, UDP_PORT)

    sock = socket.socket(socket.AF_INET,    # Internet
                         socket.SOCK_DGRAM) # UDP
    sock.bind((UDP_IP,UDP_PORT))

    while True:
        data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
        print "received message: %s from %s:%s" % (data, addr[0], addr[1])
        p = InputProcessor(sock, data, addr)
        p.start()

テスト クライアントでは、次のようなことを行います。

def send_message(ip, port, data):
    sock = socket.socket(socket.AF_INET,    # Internet
                         socket.SOCK_DGRAM) # UDP
    print "sending: %s" % data
    sock.sendto(data, (ip, port))
    sock.close()


for i in xrange(SECONDS*REQUESTS_PER_SECOND):
    data = generate_data()
    p = multiprocessing.Process(target=send_message, args=(UDP_IP,
                                                           UDP_PORT,
                                                           data))
    p.start()
    time.sleep(1/REQUESTS_PER_SECOND)

上記のコードで私が抱えている問題はREQUESTS_PER_SECOND、特定の値 (~50) より高くなると、一部のクライアント プロセスが別のプロセス宛ての応答を受信するように見えることです。つまり、プロセス #1 がプロセス #2 の応答を受信し、その逆も同様です。

私はネットワーク プログラミングに慣れていないため、明らかな何かを見落としている可能性があるため、できるだけ私のコードを批判してください。たぶん、何らかの理由で Twisted を使用する価値があり、より優れているのかもしれませんが、内部構造を理解することに非常に興味があります。ありがとう。

4

2 に答える 2

2

以前の回答によると、主な理由は、クライアントの UDP ポートに競合状態があることだと思います。クライアントコードでの受信は見られませんが、おそらくサーバー部分の受信と似ています。具体的には、50 リクエスト/秒未満の値の場合、リクエスト - レスポンスのラウンドトリップが完了し、クライアントが終了するということです。より多くのリクエストが到着すると、複数のプロセスが UDP ソケットの読み取りをブロックしている可能性があり、その場合、どのクライアント プロセスが着信メッセージを受信するかはおそらく非決定論的です。実際の設定でネットワーク遅延が大きくなる場合は、この制限に早く到達します。

于 2012-05-03T16:43:01.710 に答える
1

どうもありがとう!私のコードが以前に失敗した理由を見つけたようです。クライアント内で使用multiprocessing.Manager().dict() して、サーバーからの結果が正しいかどうかを確認していました。ただし、一連の書き込み操作をその にラップするためにロックを使用しなかったためdict()、サーバーからの出力は正しいものの、多くのエラーが発生しました。

まもなく、クライアントで、正しいサーバー応答に対して誤ったチェックを行っていました。

于 2012-05-04T05:43:24.640 に答える