绑定到0.0.0.0时查找源IP地址

时间:2014-04-04 08:25:59

标签: python python-sockets

将UDP套接字绑定到("", 1234)("0.0.0.0", 1234)时,是否可以找出它实际发送的IP地址?

正如您在下面的代码中所看到的,getsockname只告诉我我的约束。但是当我发送数据包时,我可以看到,在我的情况下,IP地址是10.0.0.2

我是否必须通过查看我的网络接口来推断此地址?如果是这样,那很好,但有一种强有力的方法吗?

from socket import *
s = socket(AF_INET, SOCK_DGRAM)
s.bind(("", 1234))
print(s.getsockname()) # prints ("0.0.0.0", 1234)
s.sendto("hello", ("10.0.0.3", 1234)) # sends from 10.0.0.2

我已经尝试过了

import socket
print(socket.gethostbyname(socket.gethostname()))

但这似乎不太可靠(在我预期10.0.0.2的情况下,我得到了127.0.1.1)。

我意识到通过绑定到0.0.0.0,我绑定到所有本地网络接口。这是否意味着当我尝试发送内容时,我的源IP地址将由路由表决定?如果是这样,我还能以健壮的方式从Python获得该地址吗?

2 个答案:

答案 0 :(得分:2)

发送时使用的IP地址将在发送数据包时由路由表确定。 可能有特定于平台的查询路由表的方法,但是相当便携的方式是 首先连接()套接字。

您也可以使用另一个套接字来查询此信息。 e.g。

from socket import *
s = socket(AF_INET, SOCK_DGRAM)
s.bind(("", 1234))
print(s.getsockname()) # prints ("0.0.0.0", 1234)
sq = socket(AF_INET, SOCK_DGRAM)
sq.connect(("10.0.0.3", 1234))
print(sq.getsockname()[0])
sq.close()
s.sendto("hello", ("10.0.0.3", 1234)) # sends from 10.0.0.2

答案 1 :(得分:1)

这通常是你不需要的答案。它可能与您的用例不符。

已经socket.gethostbyname_ex(socket.gethostname())。它显示所有可能的IP地址和主机名。你可以收到所有这些,因为你没有绑定任何特定的那些。它们将是您的源IP地址。

了解您发送的确切地址并不是必需的。如果接收器落后于NAT,进入互联网或通过VPN,接收器可能会看到另一个接收器。 接收器将知道数据包的来源并可以发送答案。

@Joachim_Pileborg也是对的。通常不会这样做。

如果您需要特定的界面,请绑定它。如果没有,你可能不需要它。