在 Python 发送广播
Sending broadcast in Python
我正在尝试学习套接字编码(在 Python 3 中),我只是想从服务器发送广播并从客户端接收广播。
我的问题是,每当我尝试将数据包发送到 255.255.255.255 时,似乎实际上什么都没有发送。
我试图用 wireshark 找到数据包,但除了在环回接口上,我找不到任何。
两台电脑之间手动输入IP可以成功发送消息,在wireshark中也看到了包。
这是客户端的代码
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.bind(("0.0.0.0", 5005))
while True:
# sock.sendto(bytes("hello", "utf-8"), ip_co)
data, addr = sock.recvfrom(1024)
print(data)
这是服务器的代码
import socket
from time import sleep
def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) # UDP
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
# sock.settimeout(2)
while True:
sock.sendto(bytes("test", "utf-8"), ("255.255.255.255", 5005))
sleep(1)
main()
抱歉,如果代码很难看,我对套接字和python都很陌生。
原因是你在一个接口上广播,在另一个接口上收听。请参阅此答案 UDP-Broadcast on all interfaces。
您需要在所有接口上进行广播,例如使用以下(纯用于演示)代码。但是,请记住,IP 广播是一项已从 IPv6 中删除的遗留功能。请改用多播。
import socket
from time import sleep
def main():
interfaces = socket.getaddrinfo(host=socket.gethostname(), port=None, family=socket.AF_INET)
allips = [ip[-1][0] for ip in interfaces]
msg = b'hello world'
while True:
for ip in allips:
print(f'sending on {ip}')
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) # UDP
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.bind((ip,0))
sock.sendto(msg, ("255.255.255.255", 5005))
sock.close()
sleep(2)
main()
如果你在这里只是想知道如何发送广播,而 Mario 的解决方案不适合你,因为你得到的 ips 列表为 127.0.1.1,所以有一个更简单的解决方案:
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) as sock:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.sendto(msg, ("255.255.255.255", 5005))
请注意,这里的缺点是它不会抛出所有网络接口,就像 Mario 解决方案一样,只是每个 OS IP table 的一个。所以请记住...
我正在尝试学习套接字编码(在 Python 3 中),我只是想从服务器发送广播并从客户端接收广播。
我的问题是,每当我尝试将数据包发送到 255.255.255.255 时,似乎实际上什么都没有发送。 我试图用 wireshark 找到数据包,但除了在环回接口上,我找不到任何。
两台电脑之间手动输入IP可以成功发送消息,在wireshark中也看到了包。
这是客户端的代码
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.bind(("0.0.0.0", 5005))
while True:
# sock.sendto(bytes("hello", "utf-8"), ip_co)
data, addr = sock.recvfrom(1024)
print(data)
这是服务器的代码
import socket
from time import sleep
def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) # UDP
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
# sock.settimeout(2)
while True:
sock.sendto(bytes("test", "utf-8"), ("255.255.255.255", 5005))
sleep(1)
main()
抱歉,如果代码很难看,我对套接字和python都很陌生。
原因是你在一个接口上广播,在另一个接口上收听。请参阅此答案 UDP-Broadcast on all interfaces。
您需要在所有接口上进行广播,例如使用以下(纯用于演示)代码。但是,请记住,IP 广播是一项已从 IPv6 中删除的遗留功能。请改用多播。
import socket
from time import sleep
def main():
interfaces = socket.getaddrinfo(host=socket.gethostname(), port=None, family=socket.AF_INET)
allips = [ip[-1][0] for ip in interfaces]
msg = b'hello world'
while True:
for ip in allips:
print(f'sending on {ip}')
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) # UDP
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.bind((ip,0))
sock.sendto(msg, ("255.255.255.255", 5005))
sock.close()
sleep(2)
main()
如果你在这里只是想知道如何发送广播,而 Mario 的解决方案不适合你,因为你得到的 ips 列表为 127.0.1.1,所以有一个更简单的解决方案:
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) as sock:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.sendto(msg, ("255.255.255.255", 5005))
请注意,这里的缺点是它不会抛出所有网络接口,就像 Mario 解决方案一样,只是每个 OS IP table 的一个。所以请记住...