我正在使用Python脚本向服务器发送UDP数据包,该服务器将注册我的脚本以接收来自服务器的通知。该协议要求我发送我自己的IP地址和端口,我希望接收这些通知,因此这应该是从服务器网络可以访问的地址。Python:获取用于将IP数据发送到特定远程IP地址的本地IP地址
解决方案应该至少可以在Windows XP及更高版本上运行,最好是Mac OS X,因为这是我的开发平台。
第一步是获取我的任何接口的IP地址。我目前正在使用通常建议的方法来解析机器自己的主机名:
def get_local_address():
return socket.gethostbyname(socket.gethostname())
这只有时才有效。当前它返回172.16.249.1
,这是VM Ware使用的虚拟接口的地址,所以这是一个问题。
更好的办法是获取默认界面的IP地址,这应该是大多数时候的正确界面。
更好的办法是通过面向连接的协议(如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]
这将阻塞,直到有TCP超时在服务器无法访问或与一个邪恶的防火墙封锁ICMP的情况下已经达到数据包。有没有更好的方法来获取这些信息?
啊,甜蜜的同理心!使用'SOCK_DGRAM',它将近乎完美!但's.getsockname()'返回'('0.0.0.0',51770)'在我的情况下。我试过's = socket.socket(socket.AF_INET,socket.SOCK_DGRAM); s.sendto(b'hello',('1.2.3.4',50000)); s.getsockname()[0]'。如果你将你的代码添加到你的答案中,那会很棒! – Feuermurmel
查看我编辑的答案。 – DNS
完美的作品;它甚至使用我不知道的[Discard Protocol](http://en.wikipedia.org/wiki/Discard_Protocol)!我用'with'语句取代了'del s'。 – Feuermurmel