【问题标题】:Python : Running loop while waiting for server socket connectionPython:等待服务器套接字连接时运行循环
【发布时间】:2014-08-18 15:56:26
【问题描述】:

我有一个 LCD 用于显示我在 XBMC 上观看的电影的时间码,我想在没有播放任何内容时显示当前日期和小时。托管 LCD 的机器正在运行 python TCPSocketServer 服务器接收要从我的 XBMC 安装中显示的文本。问题是我必须保持活动的网络连接,这样 XBMC 才能通过套接字发送小时和日期,而 LCD 可以显示它。 在我看来,最好的办法是显示托管 LCD 的机器的日期,然后在套接字处于活动状态时切换到“时间码视图”。

是否有任何 "pythonic" 方法设置 TCPSocketServer 来计算循环以在等待连接时显示日期,然后更改其行为以计算通过套接字接收的数据?

在此先感谢

【问题讨论】:

    标签: python sockets loops python-multithreading tcpsocket


    【解决方案1】:

    这里有一些代码可以满足您的需求。它启动一个 TCP 服务器,侦听发送到端口 9876 的文本。当它获得一些文本时,它会将其发送到 Display 对象。该代码还设置了一个每秒运行一次的计时器,将“空闲文本”(即:当前时间戳)发送到显示对象。

    显示器获取正常的更新文本(来自服务器),以及来自第二个线程的“空闲文本”。该对象知道它收到一些真实文本以来已经过了多长时间,并显示一条或其他消息。

    如果显示对象连接到硬件,它可以使用multiprocessing.RLock 或其他机制来保护自己。

    玩得开心!

    lcdcontrol.py 源码

    import signal, SocketServer, threading, time
    
    class Display(object):
        IDLE_TIME = 5               # seconds
    
        def __init__(self):
            self.updated = None
            self.write('Hello')
    
        def _write(self, arg):
            print 'DISPLAY:', arg
    
        def write(self, arg):
            """
            update display and 'last updated' timestamp
            """
            self._write(arg)
            self.updated = time.time()
    
        def idle(self, arg):
            """
            update display only if it's been a few seconds
            """
            if time.time() - self.updated >= self.IDLE_TIME:
                self._write(arg)
    
    class DisplayHandler(SocketServer.BaseRequestHandler):
    
        DisplayObj = None          # class var
    
        def handle(self):
            text = self.request.recv(1024).strip()
            print "{} wrote: {}".format(
                self.client_address[0], text,
                )
            # send text to LCD immediately
            self.DisplayObj.write(text)
    
    
    def check_idle(display_obj):
        """
        update display with current time if it's idle
        """
        while True:
            display_obj.idle(
                time.strftime('time: %H:%M:%S'),
            )
            time.sleep(1)
    
    
    def start_server(host, port):
        """
        start (single threaded) server
        """
        SocketServer.TCPServer(
            (host, port), 
            DisplayHandler,
        ).serve_forever()
    
    
    def main(host, port):
        display = Display()
    
        # store global display obj so Handler can get to it
        DisplayHandler.DisplayObj = display
    
        print 'serving on {}:{}'.format(host, port)
        print 'Example: echo beer | nc localhost {}'.format(port)
        print
    
        server_t = threading.Thread(
            target=start_server, args=(host, port)
        )
        server_t.daemon = True
        server_t.start()
    
        idle_t = threading.Thread(
            target=check_idle, args=[display],
            )
        idle_t.daemon = True
        idle_t.start()
    
        # wait for control-C to interrupt
        try:
            signal.pause()
        except KeyboardInterrupt:
            pass
    
    if __name__ == "__main__":
        main("localhost", 9876)
    

    样品运行

    这里我启动了服务器,等待了几秒钟,然后输入 fortune -s | nc localhost 9876 发送一个简短的幸运饼干到我的 LCD 服务器。

    注意“空闲计时器”停在:07,输出幸运饼干,等待五秒钟,然后继续:13:14。该消息显示五秒钟,然后切换回空闲时间戳。

    python ./lcdcontrol.py
    DISPLAY: Hello
    serving on localhost:9876
    Example: echo beer | nc localhost 9876
    
    DISPLAY: time: 13:08:06
    DISPLAY: time: 13:08:07
    127.0.0.1 wrote: Some people need a good imaginary cure for their painful imaginary ailment.
    DISPLAY: Some people need a good imaginary cure for their painful imaginary ailment.
    DISPLAY: time: 13:08:13
    DISPLAY: time: 13:08:14
    DISPLAY: time: 13:08:15
    DISPLAY: time: 13:08:16
    

    【讨论】:

    • @FabriceFRANCOIS 如果答案对您有帮助,请将其选为“回答问题”——谢谢
    • 干得好!!!!您的代码运行良好!非常感谢您的帮助!我确信真相在于多任务处理:-P
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-13
    • 2018-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-10
    • 1970-01-01
    相关资源
    最近更新 更多