二,UDP协议
在.NET中UDP协议可以通过以下4中方式来实现。
1.WinSock API
2.WinSock 非托管 API
3.Socket
4.UdpClient
前两种都是利用操作系统或者第三方的网络编程API实现,致使程序员必须对网络底层知识有很好的了解。Socket是Winsock的一个包装器,而UdpClient是Socket高级别的抽象。
(1)创建UdpClient实例
UdpClient() ,以缺省方式初始化UdpClient,IP地址和端口号系统自动指定;
UdpClient(AddressFamily) 以指定地址族初始化;
UdpClient(Int32) 以指定的端口号初始化
UdpClient(IPEndPoint) 以指定的本地终结点初始化
(2)指定连接信息
由于UDP是无连接传输协议,所以不需要建立连接,可用以下两种方式指定默认远程主机
使用远程主机名和端口号作为参数创建UdpClient类的实例。
创建UdpClient类的实例,然后调用Connect方法。
收信息
// 接受消息
private void btnReceive_Click(object sender, EventArgs e)
{
// 创建接收套接字
IPAddress localIp = IPAddress.Parse(tbxlocalip.Text);
IPEndPoint localIpEndPoint = new IPEndPoint(localIp, int.Parse(tbxlocalPort.Text));
receiveUpdClient = new UdpClient(localIpEndPoint);
Thread receiveThread = new Thread(ReceiveMessage);
receiveThread.Start();
}
// 接收消息方法
private void ReceiveMessage()
{
IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
while (true)
{
try
{
// 关闭receiveUdpClient时此时会产生异常
byte[] receiveBytes = receiveUpdClient.Receive(ref remoteIpEndPoint);
// 这时候的remoteIpEndPoint被改写,变成了发送端的终结点
string message = Encoding.Unicode.GetString(receiveBytes);
}
catch
{
break;
}
}
}
发信息
private void btnSend_Click(object sender, EventArgs e)
{
// 选择发送模式
if (chkbxAnonymous.Checked == true)
{
// 匿名模式(套接字绑定的端口由系统随机分配)
sendUdpClient = new UdpClient(0);
}
else
{
// 实名模式(套接字绑定到本地指定的端口)
IPAddress localIp = IPAddress.Parse(tbxlocalip.Text);
IPEndPoint localIpEndPoint = new IPEndPoint(localIp, int.Parse(tbxlocalPort.Text));
sendUdpClient = new UdpClient(localIpEndPoint);
}
Thread sendThread = new Thread(SendMessage);
sendThread.Start(tbxMessageSend.Text);
}
// 发送消息方法
private void SendMessage(object obj)
{
string message = (string)obj;
byte[] sendbytes = Encoding.Unicode.GetBytes(message);
IPAddress remoteIp = IPAddress.Parse(tbxSendtoIp.Text);
IPEndPoint remoteIpEndPoint = new IPEndPoint(remoteIp, int.Parse(tbxSendtoport.Text));
sendUdpClient.Send(sendbytes, sendbytes.Length, remoteIpEndPoint);
sendUdpClient.Close();
}
再来看看多播编程:
1,多播是一种允许一个或多个发送者将单一的数据包同时发送到多个接收者的网络技术。如上面的发送代码可以看出,发送时,要指定发送的remoteIpEndPoint,就是指定发送的地址,只是单一的发送,如果像视频会议,单一的数据包,需要多个地址接收,就需要多播的技术支持了。
一个多播组由若干个主机构成,当某源主机要将数据发送给某个多播组上所有主机时,首先需要构造一个能够标识该多播组的IP数据包,然后以尽力而为的方式转发给对应多播组中的各个主机。为了标识多播组,在TCP/IP中引入了IP多播地址,每个多播组都需要一个IP多播地址来标识。在TCP/IP协议族中,IP地址方案专门为多播划出了一个地址范围。例如IPV4中的224.0.0.0~239.255.255.255,并将D类地址划分为局部链接多播地址,预留多播地址和管理权限多播地址
2,.Net中的多播编程
在.Net中,多播只支持UDP,需要UdpClient类实现多播数据的发送和接收。
多播数据的发送
对于多播数据的发送,与普通的基于UDP协议的数据传输不同的是,必须使用一个多播地址,范围是224.0.0.0~239.255.255.255.
//终结点是一个多播地址 224.0.0.2
IPEndPoint broadcastIpEndPoint = new IPEndPoint(IPAddress.Parse("224.0.0.2"), 8002);
byte[] messagebytes = Encoding.Unicode.GetBytes("welcome");
UdpClient sendUdpClient = new UdpClient();
//发送的终结点由原先单一的节点,变成了多播地址的节点,这样,如果某个节点加入多播地址,就可以接收到所需的信息
sendUdpClient.send(messagebytes,messagebytes.Length,broadcastIpEndPoint);
sendUdpClient.Close();
多播数据的接收
在UdpClient中提供了JoinMulticastGroup方法来实现加入多播组的操作。调用joinMulticastGroup方法后,基础Socket将IGMP数据包发到路由器,请求成为多播组成员。如果指定的地址在多播地址范围之外,或者请求的路由器不支持多播,UdpClient类触发SocketException异常。而DropMulticastGroup是UdpClient从多播组中收回,将不能接收发送到该组的数据包。
IPEndPoint localIpEndPoint = new IPEndPoint("127.0.0.1",6001);
UdpClient receiveUdpClient = new UdpClient(localIpEndPoint);
//加入组播地址,可以接收组播信息
receiveUdpClient.JoinMulticastGroup("224.0.0.2");
receiveUdpClient.Ttl = 50;
IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] receiveBytes = receiveUdpClient.Receive(ref remoteIpEndPoint);
string receivemessage = Encoding.Unicode.GetString(receiveBytes);