2

私が直面している問題を小さな例で示します。

class TestProtocol(basic.LineReceiver):
    def lineReceived(self, line):
        print line

telnetクライアントを使用してサーバーに接続している限り、すべて正常に機能します。ただし、回線は受信されません。接続して、netcatを使用してデータを送信します。これは、デフォルトの区切り文字がねじれた「\ r\n」であることに関係しているように感じます。

クライアントに接続するときに両方のクライアント(telnetとnc)が同じように動作するようにサーバーを作成するにはどうすればよいですか?

4

3 に答える 3

4

LineReceiver1 つの区切り文字のみをサポートします。指定できますが、一度に指定できるのは 1 つだけです。一般に、複数の区切り記号をサポートする場合は、それをサポートする新しいプロトコルを実装する必要があります。回線ベースのプロトコルの実装方法については、LineReceiver の実装を参照してください。

netcat は入力したものを送信するため、区切り文字は多くの場合 \n です (ただし、プラットフォームや端末エミュレーターによって異なる場合があります)。デフォルトのdelimiterの部分文字列である \n の特殊なケースについては、使用できる別のトリックがあります。toを設定し、渡された行の末尾があればそれを取り除きます。LineReceiver\r\nTestProtocol.delimiter"\n""\r"lineReceived

class TestProtocol(basic.LineReceiver):
    delimiter = "\n"

    def lineReceived(self, line):
        print line.rstrip("\r")
于 2011-02-23T13:23:01.277 に答える
3

もう 1 つの回避策はnc-Cスイッチを使用することです。

マニュアルから:

-C 行末として CRLF を送信する

または@CraigMcQueenが提案したように:

-cスイッチ付きソケット(Ubuntuパッケージ

于 2012-07-16T17:29:36.850 に答える
0

TwistedLineReceiverとは、 LineOnlyReceiver1 つの行末区切り文字のみをサポートします。

UniversalLineReceiverおよびのコードを次に示します。これらは、ユニバーサル行末 (CR+LF、CR、または LF の任意の組み合わせ) をサポートするメソッドUniversalLineOnlyReceiverをオーバーライドします。dataReceived()改行は、正規表現 object で検出されますdelimiter_re

これらは、私が望むよりも多くのコードを含む関数をオーバーライドするため、基になる Twisted の実装が変更されると壊れる可能性があることに注意してください。Twisted 13.2.0 で動作することをテストしました。本質的な変更は の使用ですdelimiter_re。モジュールsplit()から。re

# Standard Python packages
import re

# Twisted framework
from twisted.protocols.basic import LineReceiver, LineOnlyReceiver

class UniversalLineReceiver(LineReceiver):
    delimiter_re = re.compile(br"\r\n|\r|\n")
    def dataReceived(self, data):
        """
        Protocol.dataReceived.
        Translates bytes into lines, and calls lineReceived (or
        rawDataReceived, depending on mode.)
        """
        if self._busyReceiving:
            self._buffer += data
            return

        try:
            self._busyReceiving = True
            self._buffer += data
            while self._buffer and not self.paused:
                if self.line_mode:
                    try:
                        line, remainder = self.delimiter_re.split(self._buffer, 1)
                    except ValueError:
                        if len(self._buffer) > self.MAX_LENGTH:
                            line, self._buffer = self._buffer, b''
                            return self.lineLengthExceeded(line)
                        return
                    else:
                        lineLength = len(line)
                        if lineLength > self.MAX_LENGTH:
                            exceeded = self._buffer
                            self._buffer = b''
                            return self.lineLengthExceeded(exceeded)
                        self._buffer = remainder
                        why = self.lineReceived(line)
                        if (why or self.transport and
                            self.transport.disconnecting):
                            return why
                else:
                    data = self._buffer
                    self._buffer = b''
                    why = self.rawDataReceived(data)
                    if why:
                        return why
        finally:
            self._busyReceiving = False

class UniversalLineOnlyReceiver(LineOnlyReceiver):
    delimiter_re = re.compile(br"\r\n|\r|\n")
    def dataReceived(self, data):
        """
        Translates bytes into lines, and calls lineReceived.
        """
        lines = self.delimiter_re.split(self._buffer+data)
        self._buffer = lines.pop(-1)
        for line in lines:
            if self.transport.disconnecting:
                # this is necessary because the transport may be told to lose
                # the connection by a line within a larger packet, and it is
                # important to disregard all the lines in that packet following
                # the one that told it to close.
                return
            if len(line) > self.MAX_LENGTH:
                return self.lineLengthExceeded(line)
            else:
                self.lineReceived(line)
        if len(self._buffer) > self.MAX_LENGTH:
            return self.lineLengthExceeded(self._buffer)
于 2015-01-07T02:42:43.453 に答える