簡體   English   中英

關於此代碼使用套接字接收多播的結論是否合理?

[英]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_namesock是相同的嗎? 我也建議使用Python 3,因為Python 2快要死了

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM