终于忍受不了每次都布置《XX管理系统》这样的东西了,同学们,让我们玩点传统的。民意结果出来了,题目分别是:像飞鸽传书那样的即时通讯工具、影音播放器、系统维护工具、后门木马、俄罗斯方块游戏、淘宝那样的网站。后悔了,头大了。没办法,只好再次回到N年前,当我还年青的时候,谁能想到还有今天的色戒……
![](https://ucc.alicdn.com/notfound.png?x-oss-process=image/resize,w_1400/format,webp)
飞鸽传书的源代码我曾经拜读过,说实话,没有读明白。而今,我们用最简单的办法实现吧。那就是把侦听和发送都放到同一端,也就是即不断侦听,又可以发送出去数据。
要使用 UDP 发送数据文报,必须知道承载所需服务的网络设备的网络地址以及该服务用于通信的 UDP 端口号。
下面这段代码演示了监听演示:
public void StartListenerConsoleDemo()
{
bool done = false;
{
bool done = false;
UdpClient listener = new UdpClient(listenPort);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort);
try
{
while (!done)
{
Console.WriteLine("Waiting for broadcast");
byte[] bytes = listener.Receive(ref groupEP);//注意在这里线程会挂起
{
while (!done)
{
Console.WriteLine("Waiting for broadcast");
byte[] bytes = listener.Receive(ref groupEP);//注意在这里线程会挂起
Console.WriteLine("Received broadcast from {0} :\n {1}\n",
groupEP.ToString(),
Encoding.UTF8.GetString(bytes, 0, bytes.Length));
}
groupEP.ToString(),
Encoding.UTF8.GetString(bytes, 0, bytes.Length));
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
listener.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
listener.Close();
}
}
其中listenPort表示监听端口号,以下雷同。发送代码演示如下,注意为了兼容汉字,最好用UTF8代码:
public void Send(string toIP,string message)
{
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
{
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPAddress broadcast = IPAddress.Parse(toIP);
byte[] sendbuf = Encoding.UTF8.GetBytes(message);
IPEndPoint ep = new IPEndPoint(broadcast, listenPort);
IPEndPoint ep = new IPEndPoint(broadcast, listenPort);
s.SendTo(sendbuf, ep);
}
}
既然监听和发送模块都有了,剩下的就是组合了。监听功能当然要时刻监听,这就是为什么耳朵不能关闭,而眼睛可以。分给它一个线程,不间断监听。OK了。
但是在退出程序时,用Thread的join方法却结束不了线程,当然是因为监听线程在Receive地方挂住了,所以可以给自己发个空数据Send("127.0.0.1", "")来结束
(完)
本文转自 王杰瑞 51CTO博客,原文链接:http://blog.51cto.com/wangjierui/55877,如需转载请自行联系原作者