Gor*_*ley 89
这对我有用:
接收
import socket
import struct
MCAST_GRP = '224.1.1.1'
MCAST_PORT = 5007
IS_ALL_GROUPS = True
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if IS_ALL_GROUPS:
# on this port, receives ALL multicast groups
sock.bind(('', MCAST_PORT))
else:
# on this port, listen ONLY to MCAST_GRP
sock.bind((MCAST_GRP, MCAST_PORT))
mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
while True:
print sock.recv(10240)
Run Code Online (Sandbox Code Playgroud)
发送
import socket
MCAST_GRP = '224.1.1.1'
MCAST_PORT = 5007
# regarding socket.IP_MULTICAST_TTL
# ---------------------------------
# for all packets sent, after two hops on the network the packet will not
# be re-sent/broadcast (see https://www.tldp.org/HOWTO/Multicast-HOWTO-6.html)
MULTICAST_TTL = 2
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, MULTICAST_TTL)
sock.sendto("robot", (MCAST_GRP, MCAST_PORT))
Run Code Online (Sandbox Code Playgroud)
它基于http://wiki.python.org/moin/UdpCommunication中不起作用的示例.
我的系统是... Linux 2.6.31-15-generic#50-Ubuntu SMP Tue 11月10日14:54:29 UTC 2009 i686 GNU/Linux Python 2.6.4
小智 17
广播到组播组的组播发送方:
#!/usr/bin/env python
import socket
import struct
def main():
MCAST_GRP = '224.1.1.1'
MCAST_PORT = 5007
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32)
sock.sendto('Hello World!', (MCAST_GRP, MCAST_PORT))
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
从多播组读取并将十六进制数据打印到控制台的多播接收器:
#!/usr/bin/env python
import socket
import binascii
def main():
MCAST_GRP = '224.1.1.1'
MCAST_PORT = 5007
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
try:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
except AttributeError:
pass
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1)
sock.bind((MCAST_GRP, MCAST_PORT))
host = socket.gethostbyname(socket.gethostname())
sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(host))
sock.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP,
socket.inet_aton(MCAST_GRP) + socket.inet_aton(host))
while 1:
try:
data, addr = sock.recvfrom(1024)
except socket.error, e:
print 'Expection'
hexdata = binascii.hexlify(data)
print 'Data = %s' % hexdata
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
st0*_*0ne 12
更好用:
sock.bind((MCAST_GRP, MCAST_PORT))
Run Code Online (Sandbox Code Playgroud)
代替:
sock.bind(('', MCAST_PORT))
Run Code Online (Sandbox Code Playgroud)
因为,如果要在同一端口上侦听多个多播组,您将获得所有侦听器上的所有消息.
小智 7
为了加入多播组,Python 使用原生 OS 套接字接口。由于 Python 环境的可移植性和稳定性,许多套接字选项直接转发到本地套接字 setsockopt 调用。组播操作模式,例如加入和删除组成员身份,setsockopt
只能通过。
接收组播 IP 数据包的基本程序如下所示:
from socket import *
multicast_port = 55555
multicast_group = "224.1.1.1"
interface_ip = "10.11.1.43"
s = socket(AF_INET, SOCK_DGRAM )
s.bind(("", multicast_port ))
mreq = inet_aton(multicast_group) + inet_aton(interface_ip)
s.setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP, str(mreq))
while 1:
print s.recv(1500)
Run Code Online (Sandbox Code Playgroud)
首先它创建套接字,绑定它并通过发出setsockopt
. 最后它永远接收数据包。
发送组播 IP 帧很简单。如果您的系统中有单个 NIC,则发送此类数据包与通常的 UDP 帧发送没有区别。您只需要在sendto()
方法中设置正确的目标 IP 地址即可。
我注意到很多关于互联网的例子实际上是偶然的。即使在官方python文档中。他们所有人的问题都在错误地使用 struct.pack。请注意,典型示例使用4sl
as 格式,它与实际的 OS 套接字接口结构不一致。
我将尝试描述在对 python 套接字对象执行 setsockopt 调用时会发生什么。
Python 将 setsockopt 方法调用转发到本机 C 套接字接口。Linux 套接字文档(请参阅参考资料man 7 ip
)介绍ip_mreqn
了 IP_ADD_MEMBERSHIP 选项的两种结构形式。最短的格式是 8 字节长,较长的是 12 字节长。上面的示例生成 8 字节setsockopt
调用,其中前四个字节定义multicast_group
,第二个四个字节定义interface_ip
。
归档时间: |
|
查看次数: |
104339 次 |
最近记录: |