gpt4 book ai didi

Python:获取用于将IP数据发送到特定远程IP地址的本地IP地址

转载 作者:太空狗 更新时间:2023-10-29 18:28:19 25 4
gpt4 key购买 nike

我正在使用 Python 脚本将 UDP 数据包发送到服务器,该服务器将注册我的脚本以接收来自服务器的通知。该协议(protocol)要求我发送自己的 IP 地址和端口,以便接收这些通知,因此这应该是一个可从服务器网络访问的地址。

解决方案至少应该适用于 Windows XP 及更高版本,最好是 Mac OS X,因为这是我的开发平台。

第一步是获取我的任何接口(interface)的 IP 地址。我目前正在使用通常建议的方法来解析机器自己的主机名:

def get_local_address():
return socket.gethostbyname(socket.gethostname())

这只是有时有效。目前它返回 172.16.249.1,这是 VM Ware 使用的虚拟接口(interface)的地址,所以这是一个问题。

更好的方法是获取默认接口(interface)的 IP 地址,大多数时候应该是正确的。

更好的方法是通过面向连接的协议(protocol)(如 TCP)获取用于连接到服务器的实际 IP 地址。我实际上可以获得该地址,但并非没有尝试打开连接:

def get_address_to_connect_to(server_addr):
non_open_port = 50000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
s.connect((server_addr, non_open_port))
except socket.error:
pass
else:
s.close() # just in case

return s.getsockname()[0]

如果服务器无法访问或中间的恶意防火墙阻止 ICMP 数据包,这将阻塞直到达到某个 TCP 超时。有没有更好的方法来获取这些信息?

最佳答案

我不得不解决一次同样的问题,并花了相当多的时间试图找到更好的方法,但没有成功。我也是从 gethostname 开始的,但是和你一样发现它并不总是返回正确的结果,甚至在主机文件有问题的情况下会抛出异常。

我能找到的跨平台可靠工作的唯一解决方案是尝试连接,正如您正在做的那样。代码的一项改进是使用 UDP 而不是 TCP,即 SOCK_DGRAM 而不是 SOCK_STREAM。这避免了连接超时,并且函数立即完成。

如果您要将此代码部署到可能正在运行防火墙的客户端位置,请确保记录它执行此检查的事实。否则,他们可能会看到针对端口 50000 的出站连接的防火墙警告,不理解其用途,并将其视为错误。

编辑:这是我使用的大致代码:

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

try:
s.connect((host, 9))
client = s.getsockname()[0]
except socket.error:
client = "Unknown IP"
finally:
del s
return client

我认为您得到的是 0.0.0.0,因为您在调用 getsockname 之前关闭了套接字。另一个技巧是我对端口 9 的使用;它是 RFC863 UDP 丢弃端口,因此比一些随机的高编号端口稍微不奇怪。

关于Python:获取用于将IP数据发送到特定远程IP地址的本地IP地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7334349/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com