[英]How to send data with Python over UDP from remote machine (client) to local machine (server)?
[英]Send UDP to local server, but not via loopback interface
我最终试图测试一个UDP客户端,并希望确保它在不通过环回接口发送数据时有效,以避免引入任何细微问题,例如校验和验证的差异( 坏UDP校验和没有效果:为什么? )。
但是,即使将数据发送到socket.gethostbyname(socket.gethostname())
的结果socket.gethostbyname(socket.gethostname())
不是127.0.0.1
,然后根据Wireshark,数据似乎通过环回接口。
下面的程序成功发送和接收b'somedata'
,并从Wireshark获得以下捕获。
import asyncio
import socket
async def server():
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
sock.setblocking(False)
sock.bind(('', 4567))
data = await loop.sock_recv(sock, 512)
print('Received', data)
async def main():
local_ip = socket.gethostbyname(socket.gethostname())
print('Local IP', local_ip) # Outputs 192.168.0.34
asyncio.ensure_future(server())
await asyncio.sleep(0)
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
sock.setblocking(False)
sock.connect((local_ip, 4567))
await loop.sock_sendall(sock, b'somedata')
await asyncio.sleep(1)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
如何将数据从本地运行的客户端发送到本地运行的服务器,但是避免环回接口并实际将数据发送到网络中?
理想情况下,答案适用于Linux和macOS。
为了“说服”网络堆栈使用以太网(或WiFi)卡而不是环回来物理传输帧,请使用广播地址。
我在Linux系统上以这种方式成功发送和接收了UDP数据包。 我用tcpdump
验证了它。 它在以太网接口上显示一个数据包,在环回时没有活动。
我使用了文字广播地址。 套接字模块文档还提到字符串'<broadcast>'
作为特殊案例地址。 我没试过。
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
sock.setblocking(False)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.connect(('192.168.0.255', 4567))
await loop.sock_sendall(sock, b'somedata')
await asyncio.sleep(1)
笔记:
setsockopt
: Python socket.error:[Errno 13]权限被拒绝 这可能是因为你的主机名指向环回地址,因此socket.gethostbyname(socket.gethostname())
将产生127.0.0.1
您需要做的是取消从主机名指向环回地址:
/etc/hosts
并注释掉127.0.0.1 YOUR_HOSTNAME
行 c:\\windows\\system32\\drivers\\etc\\hosts
,它看起来与Linux类似 在此之后如果调用socket.gethostbyname(socket.gethostname())
,它将产生DHCP分配的IP。
虽然在这种情况下,从yourip
调用yourip
可能会导致网络驱动程序通过环回接口路由包。 替代方案是在网络路由器之外使用公共IP。 您可以使用本答案中描述的外部服务
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.