我用一个小例子展示了我面临的问题。
class TestProtocol(basic.LineReceiver):
def lineReceived(self, line):
print line
只要我使用telnet客户端连接到服务器,一切正常。但是,没有接收到连接线并使用netcat发送数据。我觉得这与扭曲的默认分隔符“\ r \ n”有关。
我怎样才能建立一个服务器,使得客户端(telnet和nc)在连接到客户端时会以类似的方式运行?
答案 0 :(得分:4)
LineReceiver
仅支持一个分隔符。您可以指定它,但一次只能有一个。通常,如果要支持多个分隔符,则需要实现支持该分隔符的新协议。您可以查看the implementation of LineReceiver,了解有关如何实现基于行的协议的一些想法。
netcat发送您输入的任何内容,因此分隔符通常是\ n(但它可能因平台和终端仿真器而异,也可能因终端仿真器而异)。对于\ n的特殊情况,它是默认LineReceiver
分隔符\r\n
的子字符串,您可以使用另一种技巧。将TestProtocol.delimiter
设置为"\n"
,然后在传递给"\r"
的行的末尾删除lineReceived
(如果有的话)。
class TestProtocol(basic.LineReceiver):
delimiter = "\n"
def lineReceived(self, line):
print line.rstrip("\r")
答案 1 :(得分:3)
答案 2 :(得分:0)
Twisted的LineReceiver
和LineOnlyReceiver
仅支持一行结尾分隔符。
以下是UniversalLineReceiver
和UniversalLineOnlyReceiver
的代码,它覆盖dataReceived()
方法,支持通用行结尾(CR + LF,CR或LF的任意组合)。使用正则表达式对象delimiter_re
检测换行符。
注意,它们会覆盖函数中包含的代码比我想要的更多,因此如果底层的Twisted实现发生更改,它们可能会中断。我测试过他们使用Twisted 13.2.0。最基本的变化是使用split()
模块中的delimiter_re
。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)