我必须将侦听套接字绑定到哪个主机?

Posted

技术标签:

【中文标题】我必须将侦听套接字绑定到哪个主机?【英文标题】:What host do I have to bind a listening socket to? 【发布时间】:2011-02-24 12:47:35 【问题描述】:

我使用了 python 的 socket 模块并尝试使用打开一个监听套接字

import socket
import sys

def getServerSocket(host, port):
    for r in socket.getaddrinfo(host, port, socket.AF_UNSPEC,
                                socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
        af, socktype, proto, canonname, sa = r
        try:
            s = socket.socket(af, socktype, proto)
        except socket.error, msg:
            s = None
            continue
        try:
            s.bind(sa)
            s.listen(1)
        except socket.error, msg:
            s.close()
            s = None
            continue
        break
    if s is None:
        print 'could not open socket'
        sys.exit(1)
    return s

其中主机为无,端口为 15000。

然后程序会接受连接,但只能来自同一台机器上的连接。我必须做什么才能接受来自互联网的连接?

【问题讨论】:

【参考方案1】:

尝试 0.0.0.0。这是最常用的。

【讨论】:

【参考方案2】:

您需要绑定到您的公共 IP 地址或“所有”地址(通常用“0.0.0.0”表示)。

如果您尝试通过网络访问它,您可能还需要考虑防火墙等。

【讨论】:

我该怎么做?我知道两台电脑都在不同的无线路由器后面。 很难回答。首先尝试一下(这可能不是问题),但您需要了解如何配置所涉及的每个设备。通常只有“服务器”端需要特别注意,因为默认情况下通常不会过滤传出数据包。但 serverfault 可能是获得答案的更好地方。【参考方案3】:

第一个问题是您的 except 块正在吞噬错误而没有报告。第二个问题是您试图绑定到特定接口,而不是 INADDR_ANY。您可能绑定到“localhost”,它只接受来自本地机器的连接。

INADDR_ANY 也称为常量 0x00000000,但宏更有意义。

假设您使用的是 IPv4(即现在的“常规互联网”),请复制 socket module page 上第一个示例中的套接字/绑定代码。

【讨论】:

docs.python.org/library/socket.html#socket.getaddrinfo 没有说明任何关于接口的内容。 socket.INADDR_ANY 会取代 socket.AF_UNSPEC 或 socket.SOCK_STREAM 吗? 该接口隐含在您绑定到的地址中,在您的情况下,该地址将是变量sa。引用该手册页:“对于 IPv4 地址,接受两种特殊形式而不是主机地址:空字符串表示 INADDR_ANY ...”。对getaddrinfo 的调用将返回一个地址列表,其中没有一个是 INADDR_ANY。

以上是关于我必须将侦听套接字绑定到哪个主机?的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式获取正在侦听某个端口的进程的 pid?

无法在正在侦听的端口上远程登录 Web 服务器

在 Ruby 中将 UDP 套接字绑定到通配符主机

C# TCP 在同一个本地端口上侦听和连接

UDP Socket:一个现有的连接被远程主机强行关闭

PHP:TCP 套接字,“无法绑定地址”