这实际上是我关于Python-oauth2-BaseHTTPServer与SABNzbd+冲突的帖子的后续。
基本上,我有以下小脚本(用于创建一个本地服务器,侦听Google API oauth2凭据):
import socket
import BaseHTTPServer
from oauth2client.tools import ClientRedirectServer, ClientRedirectHandler
port_number = 0
host_name = 'localhost'
for port_number in range(8080,10000):
try:
httpd = ClientRedirectServer((host_name, port_number),
ClientRedirectHandler)
except socket.error, e:
print "socket error: " + str(e)
pass
else:
print "The server is running on: port " + str(port_number)
print "and host_name " + host_name
httpd.serve_forever()
break
在OSX上,如果我运行这个脚本两次,我会得到预期的结果:
socket error: [Errno 48] Address already in use
The server is running on: port 8081
and host_name localhost
然而,在Win7中从不同的cmd窗口运行相同的脚本,我可以很高兴地在同一端口(8080)上运行3或4台服务器,而不会引发套接字错误:
C:>netstat -abn | Findstr 8080
TCP 127.0.0.1:8080 0.0.0.0:0 LISTENING
TCP 127.0.0.1:8080 0.0.0.0:0 LISTENING
显然,Windows与大多数Unix-y系统在将多个套接字绑定到同一地址/端口方面具有不同的语义。例如,请参阅这个Python问题以及其他问题。
您不应该将多个应用程序挂接到同一个端点。
根据Ned Deily的评论,Windows对待多个套接字的方式与其他操作系统不同。
我认为在windows中执行此操作的正确方法(以及对我有效的方法,因此我将选择答案)是将端口绑定到0,并让windows自己处理它。然后,您可以使用sock.getsockname()[1]
取回使用过的端口号。
对于其他试图使用Google oauth2client.tools进行此操作的人,请参阅下面的代码:
import socket
import BaseHTTPServer
from oauth2client.tools import ClientRedirectServer, ClientRedirectHandler
port_number = 0
host_name = 'localhost'
try:
httpd = ClientRedirectServer((host_name, port_number), ClientRedirectHandler)
except socket.error, e:
print "socket error: " + str(e)
else:
print "The server is running on: port " + str(httpd.socket.getsockname()[1])
print "and host_name " + host_name
httpd.serve_forever()