我基本上是试图使用一个简单的脚本来运行两个服务器。我使用了here,there和其他解决方案。 例如,在下面的示例中,我尝试在端口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:8000和http://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:8000
和lsof -n -i4TCP:8001
时仍然有某些内容正在访问服务器任何东西……一段时间后,此错误停止出现,我实际上可以运行该脚本了。
答案 0 :(得分:2)
在启动服务器之前,添加:
socketserver.TCPServer.allow_reuse_address = True
或在调用serve_forever()
之前再次更改实例的属性:
htttp.allow_reuse_address = True
BaseServer.allow_reuse_address
服务器是否将允许地址的重用。默认为False,可以在子类中设置以更改策略。
答案 1 :(得分:0)
扩大我的评论:
在先前的编辑中,OP注册了退出处理程序atexit.register(exit_handler)
。问题是,这是否会清理您的系统资源(也就是打开的套接字)?
如果您的程序在没有关闭套接字的情况下退出(因为您用Ctrl + C中断了它),则操作系统需要花费一些时间来清理套接字(因为它们处于TIME_WAIT状态),您可以阅读有关TIME_WAIT以及有关方法的信息。避免在here中使用它。
使用退出处理程序是避免这种情况的好方法
import atexit
atexit.register(clean_sockets)
def clean_sockets():
mysocket.server_close() #