一、一个典型的使用UDPClient类实现的UDP服务器端程序,分析工作集成在代码内部
private const int srcPort = 4100;
static void Main(string[] args)
{
//使用Dns类中的GetHostAddresses方法可以得到本机上所有网卡的IP地址
IPAddress[] ipArray = Dns.GetHostAddresses(System.Environment.MachineName);Console.Clear();
int i = 0;
for (i = 0; i < ipArray.Length; i++)
{
Console.WriteLine(" {0} {1}", i, ipArray[i].ToString());
}
Console.WriteLine(" {0} All", i);
Console.WriteLine("-----------------------------------");
Console.Write("Select NIC interface to bind: ");
ConsoleKeyInfo cki = Console.ReadKey(false);
int sel = (int)(cki.KeyChar - '0');
if (sel < 0 || sel > i)
{
Console.WriteLine("");
Console.WriteLine("Error selection!");
return;
}
//选取一个IP地址做监听(绑定),也可以选取所有IP
IPEndPoint iepHost = new IPEndPoint(IPAddress.Any, srcPort);if (i > sel) iepHost.Address = ipArray[sel];
UdpClient uc = new UdpClient(iepHost);
Console.WriteLine("");
Console.WriteLine("Test Extra Server started!");
IPEndPoint iepRemote = new IPEndPoint(IPAddress.Any, 0);
while (!Console.KeyAvailable) {
Thread.Sleep(100);
try {
//利用Available属性可以使阻塞式IO当做不阻塞使用
if (uc.Available > 0) {byte[] buf = uc.Receive(ref iepRemote);
if (buf.Length < 3) continue;
switch (buf[1]) {
case 1:
buf = new byte[1460];
respWho(buf, iepHost);
uc.Send(buf, 11, iepRemote);
break;
case 2:
buf = new byte[1460];
respUpload(buf, iepHost);
uc.Send(buf, 23, iepRemote);
break;
case 3:
buf = new byte[1460];
respDownload(buf, iepHost);
uc.Send(buf, 4, iepRemote);
break;
}
}
}
//注意在使用UDP类的属性和方法时会产生异常
catch (SocketException se) {if (se.SocketErrorCode != SocketError.ConnectionReset) throw se;
}
catch (Exception e) {
Console.WriteLine("{0}", e.ToString());
}
}
二、UDPClient类的做Server/Client端要考虑的问题
如果Server/Client允许同时存在于一台主机中,要注意发送端口与接收端口不要使用同一个端口,否则Server监听端口与Client监听端口一样的话,第一、要用端口复用技术,使用(SOCKREUSED)的OPTION;第二、Client发送的报文可能Server端无法收到,而是被环回到Client接收。
三、UDPClient类非阻塞式接收用法
利用Available属性,该属性的值指示着接收缓冲区中的数据报字节数,在调用Receive接收时先查看该属性是否为0,如果不为0则表示接收缓冲区中可能有数据,但是出现异常时,该属性可能为1,这时要捕获异常进行处理
四、有时UDPClient在调用Send发送数据时,对方IP地址不存在,会产生异常(SocketError.ConnectionReset),我的判断是,对方IP地址不存在的时候,ARP解析无法完成,UDP包根本无法发送出去。所以产生异常