Python-httpd将侦听已使用的端口,而不会在windows中引发套接字错误,但不会在OS X中引发



这实际上是我关于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()

相关内容

  • 没有找到相关文章

最新更新