[英]Are my conclusions reasonable about this code receiving multicast using socket?
基於來自堆棧的MC接收器: 您如何在Python中進行UDP多播?
我想完全了解發生了什么。 這是我所了解的,而不是:
據我了解: socket_name = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
=>使用IP協議4創建套接字,該套接字將使用UDP接收MC數據報。
socket_name.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
這負責設置套接字可以使用相同地址的參數
(在這種情況下,端口,因為SO_REUSEADDR = SO_REUSEPORT用於多播)。 ( 段落多播 〜SO_REUSEADDR和SO_REUSEPORT有何不同? )
如果IS_ALL_GROUPS: socket_name.bind(('', MCAST_PORT))
表示如果IS_ALL_GROUPS
為true, IS_ALL_GROUPS
套接字綁定到任何地址,否則: socket_name.bind((MCAST_GRP, MCAST_PORT))
表示將套接字綁定到特定的給定IP地址。
mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
表示將IP地址轉換為二進制格式, socket_name.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
表示我們添加了組成員身份在這條線之后,數據包開始到達。
但是我不明白某些事情。
為什么當我在可以啟動MCAST_GRP = '239.0.1.104'
程序的地方使用IS_ALL_GROUPS = true
,為什么參數為false時,它沒有綁定到特定的多播地址? 我的邏輯是,當參數為true時,它將綁定到他從IGMP連接消息中獲取的所有MCast地址,而參數為false時,它將綁定到特定的給定地址。 我對么?
我有一個多線程程序可以分析比特率,我以列表的形式提供了多個地址。 當我將IS_ALL_GROUPS
設置為false時,程序可以正常打印,例如IS_ALL_GROUPS
10.5, 4.5, 5.0
其中每個結果都是來自唯一地址的一個流的比特率,但是所有地址共享相同的端口12345
。 當我設置IS_ALL_GROUPS
為true,計划總結成績給予20.0, 20.0, 20.0
,你知道可能是什么原因?
import socket
import struct
MCAST_GRP = '239.0.1.104'
MCAST_PORT = 12345
IS_ALL_GROUPS = True
socket_name = 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
socket_name.bind(('', MCAST_PORT))
else:
# on this port, listen ONLY to MCAST_GRP
socket_name.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 socket_name.recv(10240)
我認為發生了一些事情:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
應該是 :
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
用於IPv4的唯一基於“數據報”的協議是UDP,協議字段僅用於“原始套接字”,由tcpdump
類的程序使用。 但這沒關系。
下一個:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
只允許將多個套接字一次綁定到相同的(addr, port)
組合,即,您可以一次或快速連續地運行程序的多個副本。 我想你在說什么
下一個:
sock.bind((host, port))
說您想接收發往給定地址和端口的數據包。 特殊地址''
(即INADDR_ANY
)意味着內核不應對地址進行任何過濾。 您可能不想在此階段綁定到任何特定地址,請參閱綁定多播(UDP)套接字是什么意思?
下一個:
mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
我建議對格式字符串使用"=4sl"
,因為這給了我8個字節而不是16個字節,並且與我的Linux系統上的C struct ip_mreq
一致。 填充的差異可能只是32/64位問題,似乎沒有受到影響
概括一下:1. setsockopt(IP_ADD_MEMBERSHIP)
調用已要求內核的網絡堆棧安排(通過IGMP)發送到MCAST_GRP
多播數據包,以將其傳送到與主機相連的網絡接口。 2. bind()
調用已安排通過網絡接口接收的數據包,使其在您的進程中到達套接字。 bind()
指定INADDR_ANY
可能很重要,這樣所有到達的多播數據包都將傳遞到您的進程中,而不是被過濾
可能有用的幾個命令行是:
tcpdump -i eth0 -vv 'ip proto 2'
轉儲IGMP數據包,並且:
tcpdump -i eth0 -vv 'net 224.0.0.0/4'
哪個轉儲多播數據包
我不確定您的“多線程分析程序”在做什么,因為您沒有提供任何相關信息。 您發布的代碼也是錯誤的,大概socket_name
和sock
是相同的嗎? 我也建議使用Python 3,因為Python 2快要死了
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.