簡體   English   中英

如何防止多播套接字接收單播數據

[英]How can I keep a multicast socket from receiving unicast data

有什么方法可以防止加入多播組的套接字接收指向同一端口的單播數據?

套接字選項或ioctl也許嗎? 我看到了https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms738712%28v=vs.85%29.aspx,但這似乎只是為了過濾哪些主機可以向您發送多播,而不是誰完全可以發送單播。

我正在使用Qt應用程序,因此,如果可以在Qt的套接字框架中執行此操作,那么效果很好,如果沒有,則可以恢復到常規的舊berkley套接字,這不是問題。

到目前為止,我發現的唯一方法是非常棘手的-創建第二個UDP套接字並將其綁定到端口,然后再綁定多播套接字。 我猜測雖然還沒有找到更好的東西。

更糟糕的是:您甚至無法確定僅收到針對您加入的地址的多播流量。 您可能還會從組中接收多播流量,這些組是在同一台計算機上運行的其他進程加入的,盡管它們與您的程序無關。

最好的(因為是最便攜式的)解決方案不是嘗試使用套接字選項解決此問題,而是檢查接收到的數據包以找出它們的目標,並丟棄您不想接收的數據包。

您可以使用setsockopt(IP_PKTINFO)和recvmsg()來啟用接收到的UDP數據包上各種有用的元信息,包括通常非常有趣的目標IP地址,在您的情況下,該地址是多播地址。

將套接字綁定到多播地址,將其添加到多播組,從而設置正確的接口。 這種方法已經在linux和OSX上進行了測試。

auto fd = socket(AF_INET, SOCK_DGRAM,0);

struct sockaddr_in sa;
sa.sin_family = AF_INET;
sa.sin_port = htons(MULTICAST_PORT);
inet_pton(AF_INET, INTERFACE_ADDRESS, &sa.sin_addr);

struct sockaddr_in multicast;
multicast.sin_family = AF_INET;
multicast.sin_port = htons(MULTICAST_PORT);
inet_pton(AF_INET, MULTICAST_ADDRESS, &multicast.sin_addr);

struct ip_mreqn req = {};
req.imr_ifindex = INTERFACE_INDEX;
req.imr_multiaddr = multicast.sin_addr;
req.imr_address = sa.sin_addr;

setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &req, sizeof(req))
setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &req, sizeof(req))

bind(fd,(struct sockaddr*)&multicast, sizeof(multicast))

您可以將ip_mreqn替換為ip_mreq ,它更易於移植,並且不需要接口索引。 但是請注意,對於ipv6,需要接口索引才能加入多播組。

使用Qt,快速瀏覽https://doc.qt.io/qt-5/qtnetwork-multicastreceiver-receiver-cpp.html ,我認為您需要做的就是設置綁定調用的QHostAddress到groupAddress4 無法保證流量來自哪個設備。

您使用其他套接字的解決方案將無法移植,因為AFAIK沒有定義將一個端口上的單播流量分派到多個套接字的定義方法。 (即:可能是循環輪詢,可能是第一個綁定占用所有...)

暫無
暫無

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

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