在 python 中,如何让 UDPServer 自行关闭?

Posted

技术标签:

【中文标题】在 python 中,如何让 UDPServer 自行关闭?【英文标题】:In python, how to get a UDPServer to shutdown itself? 【发布时间】:2011-07-07 21:42:21 【问题描述】:

我用声明为服务器创建了一个类:

class myServer(socketserver.BaseRequestHandler):  
    def handle(self):  
        pass

并开始于:

someServer = socketserver.UDPServer((HOST, PORT), myServer)  
someServer.serve_forever()

我的问题是:如何让服务器自行关闭?我已经看到它有一个名为 BaseServer 的(基类的)基类,带有一个关闭方法。它可以在 someServersomeServer.shutdown() 上调用,但这来自服务器本身的外部。

【问题讨论】:

【参考方案1】:

服务器实例在处理程序类中以self.server 的形式提供。所以你可以在handle方法中调用self.server.shutdown()

【讨论】:

听起来不错。太糟糕了,我的截止日期已经过去了,但我仍然尝试使用 print("before")self.server.shutdown()print("after"),但由于某种原因它没有通过 shutdown 命令。 这对我也不起作用。程序在 windows 上死锁(不能 Control+C 出来,必须 Control+Break 出来)。似乎 server.shutdown() 不能从 RequestHandler 中调用。我的猜测是关机等待所有请求完成。请求处理程序中的那段代码等待服务器关闭。瞬间僵局。使用线程延迟一点,然后调用“server.shutdown()”就可以了。凌乱,但也许有必要? shutdown() 方法的文档字符串说 停止 serve_forever 循环。阻塞直到循环结束。这必须在 serve_forever() 在另一个线程中运行时调用,否则会死锁。参见 SocketServer.py 文件中的source。【参考方案2】:

通过使用线程。由一个线程服务并在超时后通过另一个线程。 考虑这个工作示例。为您的 UDPServer 修改它

import threading
import time
import SimpleHTTPServer
import SocketServer

PORT = 8000
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)

def worker():

    # minimal web server.  serves files relative to the
    print "serving at port", PORT
    httpd.serve_forever()

def my_service():
    time.sleep(3)
    print "I am going down"
    httpd.shutdown()

h = threading.Thread(name='httpd', target=worker)
t = threading.Thread(name='timer', target=my_service)

h.start()
t.start()

【讨论】:

雅各布 - 为什么不呢?这确实符合他的目的。 似乎是正确的,但我无法在我剩下的短时间内使用它。我应该早点问这个问题,而不是把头撞在墙上尝试不同的事情。 @Jakob,线程解决方案有效。我还没有找到另一个。你有一个工作的非线程示例吗?【参考方案3】:

你可以使用扭曲的。它是关于 python 的最佳网络库,这里是一个 UDP 服务器的例子,这里是(取自扭曲的文档)有史以来最简单的 UDP 服务器;

#!/usr/bin/env python

# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.

from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor

# Here's a UDP version of the simplest possible protocol
class EchoUDP(DatagramProtocol):
    def datagramReceived(self, datagram, address):
        self.transport.write(datagram, address)

def main():
    reactor.listenUDP(8000, EchoUDP())
    reactor.run()

if __name__ == '__main__':
    main()

当您准备好或发生特定事件时,您可以致电 self.transport.loseConnection() 将其关闭。

【讨论】:

嗯...我应该声明我不允许使用非标准库。谢谢。 为什么你不能使用除了 stdlib 之外的任何东西? socket 是一个令人讨厌的陷阱,很多人都会掉进去。 因为这是一个关于 DNS 的计算机网络课程的作业,即使套接字编程不是作业的重点,他们仍然选择禁止使用标准库以外的任何东西。具体来说,dnslib 以及其他外部库也是如此。不管怎样,最后期限已经过去了。我希望我所做的已经足够了。 整个课程的这个作业有很多问题,所以最终我重新提交了这个,这次我实现了你的想法。有效。我稍微调整了一下并使用了acquirerelease 的锁,这样服务器可以在完成后释放锁,然后负责关闭它的线程获取锁并关闭服务器。 我想我是为了换一个答案而写的。

以上是关于在 python 中,如何让 UDPServer 自行关闭?的主要内容,如果未能解决你的问题,请参考以下文章

异步udpserver接收rtp转html5

Python——socketserver编程(客户端/服务器)

后台开发小白必学服务器框架——UDPServer

Python使用socketserver建立一个异步TCP服务器

Python基础:网络编程socketserver高级篇

socket编程学