在C#中实现局域网中不在同一子网的两个机器双向UDP组播
2024-08-08
49
需求描述
在设备搜索相关的协议中,UDP被广泛使用,当不知道对方真实IP地址,并且可能两台机器不在同一个子网下,此时就不能直接使用UDP通讯,换句话说,不在相同子网下的两台机器(例如如子网掩码为255.255.255.0,机器A:192.168.11.11,机器B:192.168.1.101),普通的TCP或UDP发送都无法直接到达对方,此时就需要使用UDP的组播模式。接下来就介绍一下在C#中双向组播的实现。
实现代码
Server端
使用UDP组播,并没有服务端和客户端之分,只是在具体应用中,根据应用具体的逻辑,可以将一端的业务逻辑划分为服务端,另一端为客户端。因此,这里Server端的代码如下:
Socket udpServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
udpServerSocket.ReceiveTimeout = 1000;
udpServerSocket.MulticastLoopback = false; //禁用本地组播回环,否则自己发送的组播消息自己也会收到,形成死循环
udpServerSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, //加入组播
new MulticastOption(IPAddress.Parse(224.0.0.22), IPAddress.Any));
udpServerSocket.Bind(new IPEndPoint(IPAddress.Any, 18000));
byte[] buf = new byte[1024];
while (true)
{
EndPoint endpoint = new IPEndPoint(IPAddress.Any, 0);
int recvCount = udpServerSocket.ReceiveFrom(buf, ref endpoint);
Console.WriteLine(Receive {0} bytes from {1}., recvCount, endpoint);
Console.WriteLine(Receive message: {0}, Encoding.Default.GetString(buf));
var txEdp = new IPEndPoint(IPAddress.Parse(224.0.0.22), 18000);
udpServerSocket.SendTo(Encoding.Default.GetBytes(Hi!), txEdp);
Console.WriteLine(Send \Hi!\ to {0}., txEdp);
}
Client端
客户端的代码如下:
Socket UDPSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
UDPSocket.ReceiveTimeout = 10000;
UDPSocket.ExclusiveAddressUse = false;
UDPSocket.MulticastLoopback = false;
UDPSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
UDPSocket.Bind(new IPEndPoint(IPAddress.Any, 18000));
UDPSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse(224.0.0.22)));
var txEdp = new IPEndPoint(IPAddress.Parse(224.0.0.22), 18000);
byte[] buf = new byte[1024];
while (true)
{
UDPSocket.SendTo(Encoding.Default.GetBytes(Hello!), txEdp);
Console.WriteLine(Send \Hello!\ to {0}., txEdp);
EndPoint endpoint = new IPEndPoint(IPAddress.Any, 0);
int recvCount = UDPSocket.ReceiveFrom(buf, ref endpoint);
Console.WriteLine(Receive {0} bytes from {1}., recvCount, endpoint);
Console.WriteLine(Receive message: {0}, Encoding.Default.GetString(buf));
Thread.Sleep(1000);
}
运行结果
运行环境:
机器A:Ubuntu虚拟机,桥接网卡,IP地址为静态指定:192.168.11.11
机器B:Windows的机器,与机器A桥接网卡连接同一交换机,IP机制为动态获取:192.168.1.101
以上两个机器,如果是简单的TCP或UDP是无法通讯的,使用以上示例代码运行结果如下:
- 服务端:
Receive 6 bytes from 192.168.1.101:18061.
Receive message: Hello!
Send Hi! to 224.0.0.22:18000.
- 客户端:
Send Hello! to 224.0.0.61:18000.
Receive 3 bytes from 192.168.11.11:18000.
Receive message: Hi!
......
从运行结果可以看到,机器A和机器B可以正常实现双向通讯。
更新于:3个月前赞一波!
相关文章
文章评论
评论问答