首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Haskell中指定多播加入中的源地址?

如何在Haskell中指定多播加入中的源地址?
EN

Stack Overflow用户
提问于 2014-10-01 02:29:03
回答 1查看 617关注 0票数 4

在网络多播Haskell文档中,我看到了一个函数

代码语言:javascript
复制
setInterface :: Socket -> HostName -> IO ()
Set the outgoing interface address of the multicast.

如何使用它在多播加入中指定源地址?以下代码在运行时会生成给定的输出。(为保护隐私而屏蔽的IP地址)

代码

代码语言:javascript
复制
import Network.BSD
import Network.Socket hiding (send, sendTo, recv, recvFrom)
import Network.Socket.ByteString
import Network.Multicast hiding (multicastReceiver)
import Text.Printf
import Data.ByteString as B hiding (putStrLn)

sourceIP = "192.168.MMM.NNN"
mcastIP = "224.0.XXX.YYY"
mcastPort = 32101

mcastLoop :: Socket -> IO ()
mcastLoop sock = do
    (msg, addr) <- recvFrom sock 1024
    printf "%s-> %s\n" (show addr) (show . B.unpack $ msg)
    mcastLoop sock 

multicastReceiver :: HostName -> PortNumber -> IO Socket
multicastReceiver host port = do
    proto <- getProtocolNumber "udp"
    sock  <- socket AF_INET Datagram proto
    setInterface sock sourceIP

{-# LINE 81 "src/Network/Multicast.hsc" #-}
    setInterface sock sourceIP
    bindSocket sock $ SockAddrInet port 0
    setInterface sock sourceIP
{-# LINE 82 "src/Network/Multicast.hsc" #-}
    setInterface sock sourceIP
    addMembership sock host
    return sock

main :: IO ()
main = withSocketsDo $ do
    sock <- multicastReceiver mcastIP mcastPort
    dropMembership sock mcastIP
    setInterface sock sourceIP
    addMembership sock mcastIP
    mcastLoop sock

输出

代码语言:javascript
复制
~ - sudo tcpdump -n -nn -i any "host 224.0.XXX.YYY"
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
08:00:44.463153 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:00:52.498722 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:00:58.301711 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:01:08.408710 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:02:04.104707 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:03:08.545718 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:04:02.634709 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:05:03.757718 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:06:10.600716 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:07:07.248707 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:08:10.202708 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:09:02.390708 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY

这是正在运行的C++/Haskell应用程序的比较(根据EJP的要求)

代码语言:javascript
复制
~/sandbox - sudo tcpdump -i any "host 192.168.MMM.NNN"        
[sudo] password for gresko: 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes

# C++ application started
16:15:55.490156 IP 192.168.MMM.NNN > 224.0.62.108: igmp v2 report 224.0.62.108
# C++ application killed
16:16:04.689342 IP 192.168.MMM.NNN > all-routers.mcast.net: igmp leave 224.0.62.108

# Haskell application started
# Haskell application killed
EN

回答 1

Stack Overflow用户

发布于 2014-10-03 15:49:59

Haskell的作者在他们的构造函数中没有考虑到这一点。它根本不应该接受组参数,因为它不允许您在加入组之前设置多播接口。或者,组应该是可选的。

此外,我想说的是,它们应该提供一个addMembership()覆盖或替代方案,该替代方案采用NIC地址和组地址。底层的Sockets系统调用毕竟支持它。

但是,除非Haskell的setInterface()方法根本不起作用,在这种情况下,您可以做的事情不多,否则

代码语言:javascript
复制
dropMembership()
setInterface()
addMembership()

应该行得通。

我想确认一下,在我得出setInterface()不工作的结论之前,您确实没有看到任何IGMP消息从该接口传出。

我怀疑真正发生的情况是发送者没有正确发送。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26127650

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档