【问题标题】:Run more than one server using python使用 python 运行多个服务器
【发布时间】:2019-02-03 04:15:02
【问题描述】:

我基本上是在尝试使用一个简单的脚本来运行两台服务器。我使用了herethere 等的解决方案。 例如,在下面的示例中,我尝试在端口 8000 和 8001 中托管两个目录。

import http.server
import socketserver
import os
import multiprocessing


def run_webserver(path, PORT):
    os.chdir(path)
    Handler = http.server.SimpleHTTPRequestHandler
    httpd = socketserver.TCPServer(('0.0.0.0', PORT), Handler)

    httpd.serve_forever()

    return


if __name__ == '__main__':

    # Define "services" directories and ports to use to host them
    server_details = [
        ("path/to/directory1", 8000),
        ("path/to/directory2", 8001)
    ]

    # Run servers
    servers = []
    for s in server_details: 
        p = multiprocessing.Process(
            target=run_webserver, 
            args=(s[0], s[1])
            )
        servers.append(p)  

    for server in servers:
        server.start()

    for server in servers:
        server.join()

执行下面的代码后,一切正常,我可以使用http://localhost:8000http://localhost:8001 访问这两个目录。但是,当我使用 Ctrl+C 退出脚本,然后尝试再次运行脚本时,出现以下错误:

 Traceback (most recent call last):                                                                                     
 "/home/user/anaconda3/lib/python3.6/multiprocessing/process.py", line 258, in _bootstrap           
        self.run()                                                                                                         
      File "/home/user/anaconda3/lib/python3.6/multiprocessing/process.py", line 93, in run                   
        self._target(*self._args, **self._kwargs)                                                                          
      File "repos/scripts/webhosts.py", line 12, in run_webserver                                                          
      File "/home/user/anaconda3/lib/python3.6/socketserver.py", line 453, in __init__                        
        self.server_bind()                                                                                                 
      File "/home/user/anaconda3/lib/python3.6/socketserver.py", line 467, in server_bind                     
        self.socket.bind(self.server_address)                                                                              
    OSError: [Errno 98] Address already in use 

仅当我在运行时实际访问服务器时才会弹出此错误。如果我无法访问它,我可以重新运行脚本...从错误消息看来,当输入 lsof -n -i4TCP:8000lsof -n -i4TCP:8001 时,仍有一些东西在访问服务器我什么都没有...过了一会儿,这个错误停止出现,我实际上可以运行脚本了。

【问题讨论】:

  • 有问题吗? exit_handler 内部会发生什么?您是否有机会致电shutdownserver_close
  • Ups,对不起,我之前尝试过使用它,但我没有设法让它工作,我忘了删除(我刚刚更新了问题)。

标签: python server


【解决方案1】:

在启动服务器之前,添加:

socketserver.TCPServer.allow_reuse_address = True

或在调用serve_forever()之前再次更改实例的该属性:

htttp.allow_reuse_address = True

Documentation reference:

BaseServer.allow_reuse_address

服务器是否允许重用地址。这默认为 False,并且可以在子类中设置以更改策略。

【讨论】:

    【解决方案2】:

    扩展我的评论:

    在之前的编辑中,OP 注册了一个退出处理程序 atexit.register(exit_handler)。问题是,它是否会清理您的系统资源(也就是打开的套接字)?

    如果您的程序在没有关闭套接字的情况下退出(因为您使用 Ctrl+C 中断了它),则操作系统需要一些时间来清理套接字(因为它们处于 TIME_WAIT 状态),您可以阅读有关 TIME_WAIT 以及如何在here 中避免它。

    使用退出处理程序是避免这种情况的好方法

    import atexit
    atexit.register(clean_sockets)
    
    def clean_sockets():
        mysocket.server_close() #
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-20
      • 1970-01-01
      • 2021-05-02
      • 1970-01-01
      相关资源
      最近更新 更多