Heim > Fragen und Antworten > Hauptteil
Szenario: Es gibt einen Server A und einen Client B und es besteht eine Socket-Verbindung.
Was ich jetzt schreibe, ist Teil B auf der Clientseite, die Serverseite ist unkontrollierbar.
Es stellt sich heraus, dass B zuerst ein Paket sendet, darauf wartet, dass A den angegebenen Inhalt zurückgibt, und dann sendet B das nächste Paket
def do():
s.send(...)
yield 1
s.send(...)
yield 2
# 接收到数据后的回调
def callback():
global f
next(f)
f=do()
next(f)
Jetzt möchte ich ein Timeout und eine Blockierung implementieren. Nachdem B die Daten gesendet hat, blockiert es, bis A die Daten zurückgibt (oder löst einen Fehler aus, wenn es nicht innerhalb von 5 Sekunden eine Antwort von A erhält). Sagen Sie mir bitte, wie ich das erreichen kann.
黄舟2017-05-18 11:02:46
用 Tornado 的话,写不了几行代码吧。
先作个简单的 Server ,以方便演示:
# -*- coding: utf-8 -*-
from tornado.ioloop import IOLoop
from tornado.tcpserver import TCPServer
from tornado import gen
class Server(TCPServer):
@gen.coroutine
def handle_stream(self, stream, address):
while 1:
data = yield stream.read_until('\n')
if data.strip() == 'exit':
stream.close()
break
if data.strip() == '5':
IOLoop.current().call_at(IOLoop.current().time() + 5, lambda: stream.write('ok 5\n'))
else:
stream.write('ok\n')
if __name__ == '__main__':
Server().listen(8000)
IOLoop.current().start()
然后,来实现 Client ,基本逻辑是,超时就关闭连接,然后再重新建立连接:
# -*- coding: utf-8 -*-
import functools
from tornado.ioloop import IOLoop
from tornado.tcpclient import TCPClient
from tornado import gen
def when_error(stream):
print 'ERROR'
stream.close()
main()
@gen.coroutine
def main():
client = TCPClient()
stream = yield client.connect('localhost', 8000)
count = 0
IL = IOLoop.current()
while 1:
count += 1
stream.write(str(count) + '\n')
print count, '...'
timer = IL.call_at(IL.time() + 4, functools.partial(when_error, stream))
try:
data = yield stream.read_until('\n')
except:
break
IL.remove_timeout(timer)
print data
yield gen.Task(IL.add_timeout, IOLoop.current().time() + 1)
if __name__ == '__main__':
main()
IOLoop.current().start()