UDP单播和组播通讯之C#设计笔记(十四)
创始人
2024-01-30 20:17:00

一、定义单播端口、本地IP
public const int PortU = 1136;
public static IPAddress LocalIP; /* 本地绑定的IP */
public static List multiNetIpList = new List();
public const uint IOC_IN = 0x80000000;
public const uint IOC_VENDOR = 0x18000000;
二、定义组播地址和组播UDP客户端列表
private static List MulticastClientList = new List();
private class MulticastClient
{
public IPAddress ip;
public IPEndPoint multiEndPoint;
public UdpClient udp;
public int sourceIndex = 0;
}
private static Dictionary UnicastClientDic = new Dictionary();
三、UDP初始化网络、UDP单播、组播创建、退出
public static bool UdpInit(IPAddress LocalIP)
{
UDP.LocalIP = LocalIP;
return true;
}
private static UdpClient CreateUnicastUDP(int sourceIndex)
{
try
{
//由系统提供端口号
UdpClient udp = new UdpClient(0);
uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
udp.Client.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
udp.BeginReceive(UdpRecvFunc, sourceIndex);
return udp;
}
catch (System.Exception e)
{
throw new Exception("单播创建失败. ");
}
}
private static UdpClient CreateMulticastUDP(IPEndPoint muilAddr, IPAddress sourceIP)
{
try
{
UdpClient udp = new UdpClient(new IPEndPoint(sourceIP, 0));
uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
udp.Client.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
udp.JoinMulticastGroup(muilAddr.Address, sourceIP);
udp.Client.IOControl(IOControlCode.MulticastScope, new byte[] { Convert.ToByte(3) }, null);
udp.Client.IOControl(IOControlCode.MultipointLoopback, new byte[] { Convert.ToByte(false) }, null);
List obj = new List();
obj.Add(muilAddr);
obj.Add(sourceIP);
/false: 禁止回环 true: 允许回环/
udp.MulticastLoopback = false;
udp.BeginReceive(MutilCastRecvFunc, obj);
return udp;
}
catch (System.Exception e)
{
return null;
}
}
/不同的设备选择不同的本地IP/
public static bool UdpSetLocalIP(IPAddress localIP)
{
try
{
UDP.LocalIP = localIP;
return true;
}
catch (System.Exception e)
{
return false;
}
}
/UDP网络退出时需要调用关闭UDP网络连接/
public static bool UdpEnd()
{
foreach (UdpClient udp in UnicastClientDic.Values)
{
udp.Close();
}
UnicastClientDic.Clear();
foreach (MulticastClient client in MulticastClientList)
{
client.udp.Close();
}
MulticastClientList.Clear();
return true;
}
四、单播发送与接收
//UDPClient 的创建
public static bool InitUnicastClient(int sourceIndex)
{
if (!UnicastClientDic.ContainsKey(sourceIndex))
{
UnicastClientDic.Add(sourceIndex, CreateUnicastUDP(sourceIndex));
return true;
}
return false;
}
public static bool UdpSend(IPAddress IP, ref byte[] SendData, int length)
{
return UdpSend(new IPEndPoint(IP, UDP.PortU), ref SendData, length, 0);
}
//UDP单播数据发送
public static bool UdpSend(IPEndPoint addr, ref byte[] sendData, int length, int sourceIndex)
{
try
{
if (!UnicastClientDic.ContainsKey(sourceIndex))
{
UnicastClientDic.Add(sourceIndex, CreateUnicastUDP(sourceIndex));
}
UdpClient udp = UnicastClientDic[sourceIndex];
udp.Client.SendBufferSize = 1024 * 1024;
int i = udp.Send(sendData, length, addr);
InformUI.Inform2UI(sendData, length, sourceIndex);
}
catch (Exception ex)
{
return false;
}
return true;
}
/// UDP单播接收回调函数
private static void UdpRecvFunc(IAsyncResult Result)
{
int sourceIndex = (int)Result.AsyncState;
if (UnicastClientDic.ContainsKey(sourceIndex))
{
UdpClient udp = UnicastClientDic[sourceIndex];
try
{
System.Threading.Interlocked.Exchange(ref SubDevice.LastAliveTime, Environment.TickCount);
IPEndPoint remote = null;
byte[] Buffer = udp.EndReceive(Result, ref remote);
udp.BeginReceive(UdpRecvFunc, sourceIndex);
Protocal.AddDataToList1(remote, ref Buffer, sourceIndex);
}
catch (Exception ex)
{
udp.Close();
UnicastClientDic.Remove(sourceIndex);
}
}
}
五、组播发送与接收
public static bool MutilCastSend(IPEndPoint multAddr, byte[] SendData, int length)
{
try
{
GetMultiNetIp();
foreach (MultiNetIpDic mIPDic in multiNetIpList)
{
MulticastClient client = MulticastClientList.FirstOrDefault(m => m.ip.Equals(mIPDic.ip) && m.multiEndPoint.Equals(multAddr));
if (client == null)
{
client = new MulticastClient() { ip = mIPDic.ip, multiEndPoint = multAddr, udp = CreateMulticastUDP(multAddr, mIPDic.ip), sourceIndex = mIPDic.sourceIndex };
MulticastClientList.Add(client);
}
UdpClient udp = client.udp;
udp.BeginSend(SendData, SendData.Length, client.multiEndPoint, AsyncCallback =>
{
if (AsyncCallback.IsCompleted)
{
udp.EndSend(AsyncCallback);
}
}, null);
}
}
catch (Exception ex)
{
return false;
}
return true;
}
/// UDP组播接收回调函数
private static void MutilCastRecvFunc(IAsyncResult Result)
{
List obj = Result.AsyncState as List;
IPEndPoint multAddr = obj[0] as IPEndPoint;
IPAddress sourceIP = obj[1] as IPAddress;
MulticastClient client = MulticastClientList.FirstOrDefault(m => m.ip.Equals(sourceIP) && m.multiEndPoint.Equals(multAddr));
if (sourceIP != null && client!=null)
{
UdpClient udpM = client.udp;
try
{
IPEndPoint Remote = null;
byte[] Buffer = udpM.EndReceive(Result, ref Remote);
Protocal.AddDataToList1(Remote, ref Buffer, client.sourceIndex);
udpM.BeginReceive(MutilCastRecvFunc, obj);
}
catch
{
udpM.Close();
MulticastClientList.Remove(client);
}
}
}

相关内容

热门资讯

长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
1秒多少毫秒 1秒等于多少毫秒... 长度单位换算1丈=10尺;1尺=10寸;1寸=10分;1分=10厘;1丈≈3.33米;1尺≈3.33...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
中国电信人工电话多少 中国电信... 当我们在使用中国移动、中国电信和中国联通提供的电信业务时,可能会发生争议。建议直接向服务提供商投诉,...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...