[英]Receiving multicast on linux host with multiple interfaces
我有一個運行Ubuntu 16.04的主機,該主機通過主要的有線網絡接口連接到一個網絡,並通過USB到以太網適配器連接到另一個網絡。 使用tcpdump
,我可以在兩個網絡接口上驗證傳入的多播數據包。 但是,我的應用程序沒有從輔助接口接收任何多播數據。 如果斷開電纜與主要接口的連接,然后重新啟動應用程序,則確實會從輔助接口接收數據。 只有兩個接口都連接,應用程序才不會從輔助接口接收。
我發現了一個類似的問題(帶有USB到以太網適配器的Raspberry Pi Zero,無法響應mDNS查詢)。 要解決您的問題是否相同,同時運行tcpdump時,您的應用程序是否正確接收多播流量? 使用--no-promiscuous-mode
運行tcpdump是否看不到多播流量?
如果您對兩者的回答都是肯定的,那么我找到的解決方法就是ip link set eth0 promisc on
。 我不知道這是硬件錯誤(我正在使用控創DM9601適配器,ID 0FE6:9700)還是驅動程序錯誤,但是無論哪種方式,啟用混雜模式似乎都可以解決我的多播接收問題。 或者,您可以嘗試使用更好的USB到以太網適配器。
ip_mreq
結構作為IP_ADD_MEMBERSHIP
套接字選項的選項值傳遞,以加入多播組。 從Linux文檔項目的組播編程HOWTO中 :
第一個成員
imr_multiaddr
保留要加入的組地址。 請記住,成員資格也與接口相關聯,而不僅僅是組。 這就是您必須為第二個成員提供值imr_interface
。 這樣,如果您位於多宿主主機中,則可以在多個接口中加入同一組。 您總是可以用通配符地址(INADDR_ANY
)填充最后一個成員,然后內核將處理選擇接口的任務。
IP_MULTICAT_IF
套接字選項還與多宿主主機相關,可為通過套接字發送的多播數據設置出站接口。 有關這些套接字選項, ip_mreq
結構和較新的ip_mreqn
結構的更多信息,請參見此處 。
對於在多宿主主機上使用Boost的用戶,您將需要使用本機句柄在特定接口上加入組。 從在Ubuntu 16.04上運行的Boost 1.58開始,套接字選項抽象ip::multiast::join_group()
在內核選擇的接口上加入該組,並且不允許開發人員指定接口。 套接字選項抽象ip::multicast::outbound_interface()
控制出站接口,但不影響套接字接收到的接口。
這是一個代碼示例,用於根據本地接口IP地址在特定接口上加入組:
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(discovery_ip);
mreq.imr_interface.s_addr = inet_addr(local_interface_ip);
if(setsockopt(socket_.native_handle(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))) {
... handle error ...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.