Tornado相当于native socket的recv()方法

时间:2016-04-29 21:18:38

标签: python sockets tornado

所以,我开始在我的异步套接字服务器上使用 Tornado ,一切看起来都不错,直到我发现了一个奇怪的read_bytes(num_bytes)方法。

因为我必须从Java OutputStream读取UTF,所以我不得不在Python中重写一个“解析器”,这就是代码现在的样子:

def read_utf(self, callback):
    def _utf_length(data):
        self.stream.read_bytes(data, _read_utf)
    def _read_utf(data):
        callback(struct.unpack('>H', data)[0])
    self.stream.read_bytes(2, _utf_length)

但是..它不起作用。这就是追溯的样子:

Traceback (most recent call last):
File "C:\Python27\lib\site-packages\tornado\ioloop.py", line 600, in _run_callback
ret = callback()

File "C:\Python27\lib\site-packages\tornado\stack_context.py", line 275, in null_wrapper
return fn(*args, **kwargs)

File "C:\Python27\lib\site-packages\tornado\iostream.py", line 554, in wrapper
return callback(*args)

File "C:\Python27\lib\site-packages\tornado\stack_context.py", line 275, in null_wrapper
return fn(*args, **kwargs)

File "..\streams.py", line 57, in _utf_length
self.stream.read_bytes(data, _read_utf)

File "C:\Python27\lib\site-packages\tornado\iostream.py", line 312, in read_bytes
assert isinstance(num_bytes, numbers.Integral)
AssertionError

我尝试使用self.stream.read_bytes(int(data), _read_utf),但这不起作用,因为字符串本身就是“空”。

此时我该怎么办?

1 个答案:

答案 0 :(得分:0)

您必须对_utf_length中收到的数据使用struct.unpack。 _read_utf获取您要传递给自己回调的真实数据:

def read_utf(self, callback):
    def _utf_length(data):
        length = struct.unpack('>H', data)[0]
        self.stream.read_bytes(length, _read_utf)
    def _read_utf(data):
        callback(data)
    self.stream.read_bytes(2, _utf_length)

还要考虑将其写为协程;它比一系列回调更容易理解:

@tornado.gen.coroutine
def read_utf(self):
    length_data = yield self.stream.read_bytes(2)
    length = struct.unpack('>H', length_data)[0]
    data = yield self.stream.read_bytes(length)
    raise tornado.gen.Return(data)