0

我正在尝试在我的所有网络接口(2 个 LAN,一个 wifi)上发送一个多播数据包。我最初遵循本教程

我遇到的问题是,数据包似乎只有我的一个 IP 地址。

这是我当前的代码。

private static void SendOnAllCards(int port, String address)
{
    using (Socket mSendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
    {
        mSendSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership,
                                    new MulticastOption(IPAddress.Parse(address)));
        mSendSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 255);
        mSendSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
        mSendSocket.Bind(new IPEndPoint(IPAddress.Any, port));
        IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(address), port);
        mSendSocket.Connect(ipep);


        byte[] bytes = Encoding.ASCII.GetBytes("This is my welcome message");
        mSendSocket.Send(bytes, bytes.Length, SocketFlags.None);
    }
}

我尝试手动进行:

private static void SendOnAllCards(int port, string remoteAddressSrc)
{
    foreach (IPAddress remoteAddress in Dns.GetHostAddresses(Dns.GetHostName()).Where(i=>i.AddressFamily == AddressFamily.InterNetwork))
    {

        using (Socket mSendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
        {
            mSendSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership,
                                        new MulticastOption(IPAddress.Parse(remoteAddressSrc)));
            mSendSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 255);
            mSendSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            mSendSocket.Bind(new IPEndPoint(IPAddress.Any, port));
            IPEndPoint ipep = new IPEndPoint(remoteAddress, port);
            mSendSocket.Connect(ipep);


            byte[] bytes = Encoding.ASCII.GetBytes("This is my welcome message");
            mSendSocket.Send(bytes, bytes.Length, SocketFlags.None);
        }
    }
}

这可行,但这意味着我必须创建与 IP 一样多的套接字(在此示例中,我在每次发送时创建它们,但这只是一个测试),而且我不喜欢我必须获得的方式我所有的IP。

那么这样做的正确方法是什么?

编辑第二个奖励问题:为什么当我在指定远程地址的本地 ip 中Connect指定远程地址但不在Bind?

4

2 回答 2

1

似乎我们必须在网络接口上进行迭代,在本地 IP 上进行绑定并执行 Send* To * 调用:

public void SendTestMessage()
{
    foreach (IPAddress localIp in
        Dns.GetHostAddresses(Dns.GetHostName()).Where(i => i.AddressFamily == AddressFamily.InterNetwork))
    {
        IPAddress ipToUse = localIp;
        using (var mSendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
        {
            mSendSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership,
                                        new MulticastOption(_multicastIp, localIp));
            mSendSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 255);
            mSendSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            mSendSocket.MulticastLoopback = true;
            mSendSocket.Bind(new IPEndPoint(ipToUse, _port));


            byte[] bytes = Encoding.ASCII.GetBytes("This is my welcome message");
            var ipep = new IPEndPoint(_multicastIp, _port);
            mSendSocket.SendTo(bytes, ipep);
        }
    }
}
于 2013-03-08T14:23:52.847 回答
0

您可以使用 WMI 类找到网络适配器Win32_NetworkAdapter。您可能需要优化查询实例带来的结果,因为 Windows 和第三方软件都创建了许多“虚拟适配器”。我编写了一个快速的豪华脚本来使用 WMI 检索适配器。这应该只显示具有 IP 地址的适配器。这只是为了显示您可以查询以检索激活适配器的 WMI 信息。

$networkadapters = @(Get-CimInstance -ClassName Win32_NetworkAdapter -Property *)
$networkadapters_configs = @($networkadapters | Get-CimAssociatedInstance -ResultClassName Win32_NetworkAdapterConfiguration)

0..($networkadapters.Length-1) | %{
    if($networkadapters_configs[$_].IPAddress -gt '') {
        Write-Output "Adapter #$($_)" 
        Write-Output $networkadapters[$_]
        Write-Output "Config #$($_)" 
        Write-Output $networkadapters_configs[$_]
    }
}
于 2013-03-06T16:03:21.790 回答