我最终将尝试测试UDP客户端,并希望确保在通过回送接口发送数据 not 时它可以正常工作,以避免由此引起的任何细微问题,例如校验和验证(Bad UDP checksum has no effect: why?)。
但是,即使将数据发送到不是socket.gethostbyname(socket.gethostname())
的{{1}}的结果,那么根据Wireshark的说法,数据似乎仍通过回送接口传输。
下面的程序成功发送和接收127.0.0.1
,并从Wireshark中捕获了以下内容。
b'somedata'
如何将数据从本地运行的客户端发送到本地运行的服务器,但是要避免使用环回接口,而是将数据实际发送到网络中?
理想情况下,答案适用于Linux和macOS。
答案 0 :(得分:1)
要“说服”网络堆栈使用以太网(或WiFi)卡而不是环回来物理传输帧,请使用广播地址。
我已经在Linux系统上成功发送和接收了UDP数据包。我用tcpdump
进行了验证。它显示了以太网接口上的一个数据包,而环回时没有任何活动。
我使用了原义广播地址。 socket module文档还提到了字符串'<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] Permission denied 答案 1 :(得分:0)
这可能是因为您的主机名指向回送地址,因此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。您可以按照this answer