上一节介绍了使用TCP/IP,本届介绍UDP
3.使用UDP进行多点广播
UDP不像TCP,UDP是无连接的,数据可以通过一个单独的socket被发送给多个接收者。基于UDP的操作如下:
(1)使用本地端口号或者远程主机号远程端口号创建一个System.Net.Sockets.UdpClient:
UdpClient client = new UdpClient(local_ port);
or
UdpClient client = new UdpClient(remote_host, remote_port);
(2)使用上面的UdpClient接收数据:
System.Net.IPEndPoint ep = null;
byte[] data = client.Receive(ref ep);
byte数组 data包含了接收到的数据,ep存储了发送方的ip地址。
(3)使用上面的UdpClient发送数据:
如果远程主机的IP地址和端口号已经通过构造函数传给了UdpClient,则这么写:
client.Send(data, data.Length);
否则,需要使用接收者的IPEndPoint ep:
client.Send(data, data.Length, ep);
下面的代码(empudpserver.cs)从一个远程客户端哪里接收雇员名字,然后返回它的职位:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Configuration;
class EmployeeUDPServer{
public static void Main(){
UdpClient udpc = new UdpClient(2055);
Console.WriteLine("Server started, servicing on port 2055");
IPEndPoint ep = null;
while(true){
byte[] rdata = udpc.Receive(ref ep);
string name = Encoding.ASCII.GetString(rdata);
string job = ConfigurationSettings.AppSettings[name];
if(job == null) job = "No such employee";
byte[] sdata = Encoding.ASCII.GetBytes(job);
udpc.Send(sdata,sdata.Length,ep);
}
}
}
下面是配置文件的内容:
<configuration>
<appSettings>
<add key = "john" value="manager"/>
<add key = "jane" value="steno"/>
<add key = "jim" value="clerk"/>
<add key = "jack" value="salesman"/>
</appSettings>
</configuration>
下面的代码是一个UDP客户端,对应上面的UDP服务器:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class EmployeeUDPClient{
public static void Main(string[] args){
UdpClient udpc = new UdpClient(args[0],2055);
IPEndPoint ep = null;
while(true){
Console.Write("Name: ");
string name = Console.ReadLine();
if(name == "") break;
byte[] sdata = Encoding.ASCII.GetBytes(name);
udpc.Send(sdata,sdata.Length);
byte[] rdata = udpc.Receive(ref ep);
string job = Encoding.ASCII.GetString(rdata);
Console.WriteLine(job);
}
}
}
UDP也支持多点广播,发送一条数据报给多个接收者。要实现这些,需要发送者发送一个数据报给一个IP范围,比如224.0.0.1到239.255.255.255(D型IP)。广播接收者需要加入到这个多播段,然后接收数据报。下面的代码每隔5秒发送一个数据报,内容是股价(随机产生的),IP段为230.0.0.1
using System; using System.Net; using System.Net.Sockets; using System.Text; class StockPriceMulticaster{ static string[] symbols = {"ABCD","EFGH", "IJKL", "MNOP"}; public static void Main(){ UdpClient publisher = new UdpClient("230.0.0.1",8899); Console.WriteLine("Publishing stock prices to 230.0.0.1:8899"); Random gen = new Random(); while(true){ int i = gen.Next(0,symbols.Length); double price = 400*gen.NextDouble()+100; string msg = String.Format("{0} {1:#.00}",symbols,price); byte[] sdata = Encoding.ASCII.GetBytes(msg); publisher.Send(sdata,sdata.Length); System.Threading.Thread.Sleep(5000); } } }
下面的代码加入到230.0.0.1这个多播段,接收10次股票价格,然后离开多播段
using System; using System.Net; using System.Net.Sockets; using System.Text; class StockPriceReceiver{ public static void Main(){ UdpClient subscriber = new UdpClient(8899); IPAddress addr = IPAddress.Parse("230.0.0.1"); subscriber.JoinMulticastGroup(addr); IPEndPoint ep = null; for(int i=0; i<10;i++){ byte[] pdata = subscriber.Receive(ref ep); string price = Encoding.ASCII.GetString(pdata); Console.WriteLine(price); } subscriber.DropMulticastGroup(addr); } }