简单的udp消息收发

本例内容为书上1.4.4内容的改版,主要实现服务端和客户端分离。

服务端程序:

 1  static void Main(string[] args)
 2         {
 3             int dataLength;
 4             string tmpStr;
 5             byte[] dataBytes1 = new byte[1024];
 6             //指定监听端口开始
 7             Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
 8             IPEndPoint myHost = new IPEndPoint(IPAddress.Any, 8080);
 9             //指定监听端口结束
10             EndPoint client1 = new IPEndPoint(IPAddress.Any, 8080); 
11             socket.Bind(myHost);
12             while (true)
13             {
14                 Console.WriteLine("等待接收...");
15                 dataLength = socket.ReceiveFrom(dataBytes1,ref client1);
16                 tmpStr = System.Text.Encoding.Unicode.GetString(dataBytes1, 0, dataLength);
17                 Console.WriteLine($"接收到来自{client1.ToString()}的信息:{tmpStr}");
18                 if (tmpStr == "ServerOver") break;
19             }
20             socket.Close();
21             Console.WriteLine("对方已要求服务器退出,请按回车键结束。");
22             Console.ReadLine();
23         }

客户端程序:

 1 static void Main(string[] args)
 2         {
 3             byte[] dataBytes;
 4             Socket socket =new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
 5             //指定使用哪个套接字发送开始
 6             IPEndPoint myHost = new IPEndPoint(IPAddress.Any, 8081);
 7             socket.Bind(myHost);
 8             //指定使用哪个套接字发送结束
 9             //指定服务器开始
10             IPEndPoint remoteIPEnd = new IPEndPoint(IPAddress.Parse("192.168.1.105"), 8080);
11             EndPoint remoteHost = (EndPoint)remoteIPEnd;
12             //指定服务器结束
13             Console.Write("输入发送的信息:");
14             string tmpStr = Console.ReadLine();
15             dataBytes = System.Text.Encoding.Unicode.GetBytes(tmpStr);
16             socket.SendTo(dataBytes, dataBytes.Length, SocketFlags.None, remoteHost);
17             while (true)
18             {
19                 if (tmpStr == "exit")
20                 {
21                     break;
22                 }
23                 Console.Write("输入发送信息(exit退出):");
24                 tmpStr = Console.ReadLine();
25                 dataBytes = System.Text.Encoding.Unicode.GetBytes(tmpStr);
26                 socket.SendTo(dataBytes, remoteHost);
27             }
28             socket.Close();
29             Console.WriteLine("对方已经退出了,请按回车键结束。");
30             Console.ReadLine();
31         }

运行效果:

简单的udp消息收发

 不同电脑测试也通过。

 基于此,就应当能很轻松完成P24页第4题了。


 扩展:

都写到这里了,大家结合之前的网络知识,再思考一下,如何突破单边的源地址转换限制,实现内网和公网pc收发消息?

提示:内网机器先发出消息,利用出口转换表里的地址和端口对应关系,让服务器也可以访问到客户机。

代码修改1:发送消息程序,服务器ip和端口需要在运行时由用户指定。

代码修改2:内网机器的发送和接收,使用了相同的ip和端口。必须开启端口复用才能工作。代码为:“socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);”

效果如下图:

简单的udp消息收发

 

 其中,远程桌面使用的是一台公网机器,右侧是本机。

运行顺序为图中顺序。

此时,内网机器也能够被其他内网机器连接并接收消息:

简单的udp消息收发

 

这也是qq最基本的通信原理。 

思考题:如何利用一台公网服务器,构建简单聊天室?

 

上一篇:jQuery上传剪切图片的原理和代码


下一篇:使用RetinaNet构建的人脸口罩探测器