簡單的udp消息收發


本例內容為書上1.4.4內容的改版,主要實現服務端和客戶端分離。

使用socket:

服務端程序:

int dataLength;
            string tmpStr;
            byte[] dataBytes1 = new byte[1024];
            //指定監聽端口開始
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPEndPoint myHost = new IPEndPoint(IPAddress.Any, 8080);
            //指定監聽端口結束
            EndPoint client1 = new IPEndPoint(IPAddress.Any, 8080);
            socket.Bind(myHost);
            do
            {
                Console.WriteLine("等待接收...");
                dataLength = socket.ReceiveFrom(dataBytes1, ref client1);
                tmpStr = System.Text.Encoding.Unicode.GetString(dataBytes1, 0, dataLength);
                Console.WriteLine($"接收到來自{client1.ToString()}的信息:{tmpStr}");
            }while (tmpStr.ToLower() != "serverover");
            socket.Close();
            Console.WriteLine("對方已要求服務器退出,請按回車鍵結束。");
            Console.ReadLine();

客戶端程序:

byte[] dataBytes;
            string tmpStr;
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            //指定使用哪個套接字發送開始
            IPEndPoint myHost = new IPEndPoint(IPAddress.Any, 8081);
            socket.Bind(myHost);
            //指定使用哪個套接字發送結束
            //指定服務器開始
            IPEndPoint remoteIPEnd = new IPEndPoint(IPAddress.Parse("192.168.1.105"), 8080);
            //指定服務器結束
            do
            {
                Console.Write("輸入發送信息(exit退出):");
                tmpStr = Console.ReadLine();
                dataBytes = System.Text.Encoding.Unicode.GetBytes(tmpStr);
                socket.SendTo(dataBytes, remoteIPEnd);
            } while (tmpStr.ToLower() != "exit");
            socket.Close();
            Console.WriteLine("已經退出,請按回車鍵結束。");
            Console.ReadLine();

運行效果:

 不同電腦測試也通過。

 基於此,就應當能很輕松完成P24頁第4題了。


 使用udpclient:

服務端:

static UdpClient udp;
        static void Main(string[] args)
        {
            string msg;
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9000),remote=new IPEndPoint(IPAddress.Any,0);
            udp = new UdpClient(ipep);
            do
            {
                msg = Encoding.UTF8.GetString(udp.Receive(ref remote));
                Console.WriteLine($"{remote.ToString()}:{msg}");
            }
            while (msg.ToLower() != "exit");
        }

客戶端:

static UdpClient udp;
        static void Main(string[] args)
        {
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9100);
            udp = new UdpClient(ipep);
            udp.Connect(IPAddress.Parse("127.0.0.1"), 9000);
            string msg;
            byte[] b;
            do
            {
                msg = Console.ReadLine();
                b = Encoding.UTF8.GetBytes(msg);
                udp.Send(b, b.Length);
            } while (msg.ToLower() != "exit");
        }

 


 

擴展:

都寫到這里了,大家結合之前的網絡知識,再思考一下,如何突破單邊的源地址轉換限制,實現內網和公網pc收發消息?

提示:內網機器先發出消息,利用出口轉換表里的地址和端口對應關系,讓服務器也可以訪問到客戶機。

代碼修改1:發送消息程序,服務器ip和端口需要在運行時由用戶指定。

代碼修改2:內網機器的發送和接收,使用了相同的ip和端口。必須開啟端口復用才能工作。代碼為:“socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);”

效果如下圖:

 

 其中,遠程桌面使用的是一台公網機器,右側是本機。

運行順序為圖中順序。

此時,內網機器也能夠被其他內網機器連接並接收消息:

 

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

思考題:如何利用一台公網服務器,構建簡單聊天程序?

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM