在Python中关闭/重启socket
我准备做一个简单的测试,想用PagSeguro(巴西的“PayPal”),为此我下载了他们的Python服务器来在我的本地电脑上测试。我用的是Mac,正在运行XAMPP服务器(Apache和MySQL部分在我的操作过程中是开启的)。
我的问题对懂Python和套接字的人来说应该很简单,但由于我自己在这方面的知识有限,没能把事情搞明白。
简单来说,我想知道:如何在终端中释放一个套接字,这个套接字的程序在关闭之前没有正常关闭。还有,如何写一个Python函数,让我在想关闭套接字和停止/重启服务器的时候调用。
场景是这样的:我在终端启动服务器(用命令:# sudo python ./PagSeguroServer.py),一切正常,我做了一些想做的测试。然后,我需要更改一些服务器的设置,为了让它生效,我需要重启服务器。我是通过关闭终端窗口来解决的,但当我重新打开终端并输入同样的命令来再次启动服务器时,出现了“socket.error: [Errno 48] Address already in use”的错误。好吧,我明白为什么会这样,但不知道怎么解决,于是我在网上搜索,发现有个建议是要在代码中添加
socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
。我查看了Python类,尽量把它放进去(如下所示),但问题没有解决。由于我的“搜索和拼凑”似乎没有帮助,我决定放弃,发这个定制的问题!
这是服务器代码的一部分:
class SecureHTTPServer(HTTPServer):
'''Servidor HTTPS com OpenSSL.'''
def __init__(self, server_address, HandlerClass,fpem):
BaseServer.__init__(self, server_address, HandlerClass)
ctx = SSL.Context(SSL.SSLv23_METHOD)
ctx.use_privatekey_file (fpem)
ctx.use_certificate_file(fpem)
self.socket = SSL.Connection(ctx, socket.socket(self.address_family,
self.socket_type))
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server_bind()
self.server_activate()
....
def run(HandlerClass = HTTPSHandler, ServerClass = SecureHTTPServer):
'''Roda o servidor'''
server_address = ('', 443) # (address, port)
httpd = ServerClass(server_address, HandlerClass, fpem)
httpd.serve_forever()
if __name__ == '__main__':
run()
注意:有一次我确实成功重新打开了它,那是在我添加setsockopt调用之前,我感觉套接字在超时后关闭了——我在某处读到过这个。不过,这次似乎不再发生了——我等了好几次也试过。
编辑:最后我解决了这个问题:需要杀掉占用套接字的Python进程(见jd的回答中的评论),然后添加了KeyboardInterrupt捕获,以便能够正确关闭套接字。谢谢大家!
5 个回答
在终端窗口中使用以下命令来关闭TCP端口28355:
npx kill-port 28355
在我的Python套接字服务器脚本中,我使用了以下几行代码:
import os
os.system("npx kill-port 28355")
这个命令可以解决“地址已在使用中”的错误。
在我找到的所有解决方案中,这个是唯一能解决这个错误的方法,比如启用SO_REUSEADDR选项并没有用。
你可以写一个函数来正确地关闭套接字(socket),并使用 atexit.register()
来注册这个函数,让它在程序结束时自动运行。想了解更多,可以查看这个链接:http://docs.python.org/library/atexit.html
如果你是通过按 Ctrl+C 来关闭程序的话,可以试着在你的代码里捕捉一个叫做 KeyboardInterrupt 的异常(更好的方法是处理 SIGINT 信号),这样在退出之前就可以优雅地关闭连接。
当然,这样做并不能阻止你用其他方式强行结束程序,从而导致连接不再有效,但你也可以尝试处理这些情况。