1

私は Python を初めて使います (ただし、Java でプログラミングを行ってから数年が経ちます)。単純なソケットベースのネットワーク アプリケーションに取り組んでいます (ただの楽しみです)。アイデアは、私のコードがリモート TCP エンドポイントに接続し、サーバーからクライアントにプッシュされるデータをリッスンし、これに対して何らかの解析を実行することです。

サーバー -> クライアントからプッシュされるデータは UTF-8 でエンコードされたテキストであり、各行はCRLF( \x0D\x0A) で区切られています。ご想像のとおり、クライアントがサーバーに接続し (ユーザーがキャンセルするまで)、受信した行を読み取って解析するという考え方です。

私はこれを機能させることができましたが、これが正しい方法であるかどうかはわかりません。したがって、私の実際の質問(従うべきコード):

  1. これは Python で正しい方法ですか (つまり、本当にこれほど簡単ですか)?
  2. buffers/ に関するヒント/トリック/有用なリソース (参照ドキュメントを除くasyncore)

現在、データは次のように読み取られ、バッファリングされています。

def handle_read(self):
    self.ibuffer = b""

    while True:
        self.ibuffer += self.recv(self.buffer_size)
        if ByteUtils.ends_with_crlf(self.ibuffer):
            self.logger.debug("Got full line including CRLF")
            break
        else:
            self.logger.debug("Buffer not full yet (%s)", self.ibuffer)

    self.logger.debug("Filled up the buffer with line")
    print(str(self.ibuffer, encoding="UTF-8"))

このByteUtils.ends_with_crlf関数は、バッファの最後の 2 バイトをチェックするだけです\x0D\x0A。最初の質問が主な質問です (回答はこれに基づいています) が、他のアイデアやヒントは大歓迎です。ありがとう。

4

2 に答える 2

6

TCP はストリームであり、バッファに 1 つのメッセージの終わりと次のメッセージの始まりが含まれていないという保証はありません。そのため、バッファの最後にある \n\r のチェックは、すべての状況で期待どおりに機能するとは限りません。ストリーム内の各バイトをチェックする必要があります。

また、asyncore の代わりに Twisted を使用することを強くお勧めします。このようなもの(メモリから、そのままでは機能しない可能性があります):

from twisted.internet import reactor, protocol
from twisted.protocols.basic import LineReceiver


class MyHandler(LineReceiver):

    def lineReceived(self, line):
        print "Got line:", line


f = protocol.ClientFactory()
f.protocol = MyHandler
reactor.connectTCP("127.0.0.1", 4711, f)
reactor.run()
于 2009-11-26T18:12:12.210 に答える
6

それはさらに単純です -- asynchatとそのset_terminatorメソッド (およびそのモジュール内のその他の役立つ情報) を見てください。 Twistedは桁違いにリッチで強力ですが、十分に単純なタスクの場合、asyncore と asynchat (スムーズに相互運用するように設計されています) は実際に非常に使いやすいです。

于 2009-11-26T18:16:25.023 に答える