在我所有的ip上发送一个UDP组播包
本文关键字:一个 UDP ip | 更新日期: 2023-09-27 18:02:39
我正在尝试在所有网络接口(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的方式。
那么正确的方法是什么呢?
编辑第二个附加问题:为什么当我在Connect
中指定本地ip时,它指定远程地址,但在Bind
上不起作用?
似乎我们必须在网络接口上进行迭代,在本地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);
}
}
}
您可以使用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[$_]
}
}