gpt4 book ai didi

python - 将 UDP 发送到本地服务器,但不通过环回接口(interface)

转载 作者:行者123 更新时间:2023-11-28 18:00:55 24 4
gpt4 key购买 nike

我最终试图测试一个 UDP 客户端,并希望确保它在通过环回接口(interface)而不是发送数据时正常工作,以避免由此引入的任何细微问题,例如校验和验证 ( Bad UDP checksum has no effect: why? )。

但是,即使向 socket.gethostbyname(socket.gethostname()) 的结果发送数据时,也不是 127.0.0.1,然后根据 Wireshark,数据似乎通过环回接口(interface)传输。

下面的程序成功地发送和接收了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()

enter image description here

我如何才能将数据从本地运行的客户端发送到本地运行的服务器,同时避免环回接口(interface)并将数据实际发送到网络中?

理想情况下,答案将同时适用于 Linux 和 macOS。

最佳答案

要“说服”网络堆栈使用以太网(或 WiFi)卡而不是环回物理传输帧,请使用广播地址。

我已经在我的 Linux 系统上以这种方式成功地发送和接收了一个 UDP 数据包。我用 tcpdump 验证了它。它显示以太网接口(interface)上有一个数据包,环回上没有事件。

我使用的是文字广播地址。 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)

注意事项:

  1. 同一网络上的其他主机也会​​收到 UDP 数据包。
  2. 确保防火墙/数据包过滤器(例如 Linux iptables/nftables)不会阻止数据包。
  3. 关于 setsockopt:Python socket.error: [Errno 13] Permission denied

关于python - 将 UDP 发送到本地服务器,但不通过环回接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55791513/

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