在socketserver句柄中保持连接而不轮询()

时间:2013-03-27 13:28:27

标签: python sockets events

我正在寻找一种方法来维护与python socketserver的连接。我想避免以下情况。

轮询输入

示例:

class SingleTCPHandler(SocketServer.StreamRequestHandler):
    def handle(self):
        while True:
            message = self.rfile.readline().strip()
            ... do something with message

我正在做的是不断检查是否收到了什么。我想避免这种情况,因为服务器是在Raspberry pi上运行的,所以我希望尽可能减少不必要的计算。


更新:2013年3月28日

似乎socket.recv()是一个阻塞调用。根据{{​​3}}的文档:

  

区别在于第二个处理程序中的readline()调用   多次调用recv()直到遇到换行符,   而第一个处理程序中的单个recv()调用将返回   在一次sendall()调用中从客户端发送的内容。

这意味着如果socket.recv()是阻塞调用,那么while True不会导致不断检查新消息是否已到达并且不会像我一样使用处理器最初的想法。


每封邮件一个连接

示例:

class SingleTCPHandler(SocketServer.StreamRequestHandler):
    def handle(self):
        while True:
            message = self.rfile.readline().strip()
            ... do something with message

一旦收到消息,这将关闭连接。但是,消息每60ms发送一次,因此客户端每次都会初始化一个新连接。这给连接带来了开销,应尽可能快。

问题

有没有办法获得某种“中断”?每次收到消息?

(概念)示例:

class SingleTCPHandler(SocketServer.StreamRequestHandler):
    def handle(self):
        if interrupt:
            message = self.rfile.readline().strip()
            ... do something with message

之前我曾问过类似的socketserver,但是这个问题总结了前一个问题没有直接解决的问题的实质。

1 个答案:

答案 0 :(得分:2)

我继续为我自己的利益实施了一个版本。

import asyncore, socket, time, signal, sys

finished = None

class EchoHandler(asyncore.dispatcher_with_send):

    def handle_read(self):
        data = self.recv(8192)
        if data:
            self.send(data)

    def handle_close(self):
        print 'Closing connection from %s' % repr(self.getpeername())
        self.close()

class Listner(asyncore.dispatcher):

    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.set_reuse_addr()
        self.bind((host, port))
        self.listen(5)
        self.number_accepted = 1

    def handle_accept(self):
        pair = self.accept()
        if pair is not None:
            sock, addr = pair
            print 'Incoming connection from %s' % repr(addr)
            handler = EchoHandler(sock)
            self.number_accepted-=1
        if self.number_accepted < 0:
            finished = 1

client = Listner('127.0.0.1', 1033)
asyncore.loop()

while not finished:
    time.sleep(1)