我們知道,對於UDP協議的通信,除了可以用來聊天外,可以發送廣播數據。只要向廣播地址的某個端口發送數據就可以進行廣播,子網中只要監聽該端口的socket就能收到廣播消息。
最簡單的方法就是向255.255.255.255發送消息,這樣就可以在本地網絡中廣播了,由於路由器不轉發對該地址所發送的內容,所以只能用於本地網絡。但這已經夠用了,至少連接到同一個路由器的設備都能收到消息。
下面,咱們就來演示一下,如何進行廣播。
先看接收端的實現。
RT庫API提供了一個名為DatagramSocket的類,就是用來實現UDP通信的。對於數據接收者,處理過程如下:
1、new一個實例。
2、處理MessageReceived事件,只要有新的消息收到,就會引發該事件。
3、調用BindServiceNameAsync方法綁定一個本地端口,只要發送到該端口的數據都會被接收;或者調用BindEndpointAsync方法綁定本地結點,此方法需要明確指定一個本機地址。
4、在MessageReceived事件的處理中,通過事件參數可以得到一些基本信息。比如,LocalAddress本機地址,RemotePort遠程端口,RemoteAddress遠程主機地址。
具體如下面代碼。
private async void OnMsgReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args) { string remoteaddr = args.RemoteAddress.DisplayName; DataReader reader = args.GetDataReader(); reader.UnicodeEncoding = UnicodeEncoding.Utf8; // 讀長度 uint len = reader.ReadUInt32(); // 讀內容 string msg = reader.ReadString(reader.UnconsumedBufferLength); …… }
調用事件參數的GetDataStream方法可以得到輸入流,用來讀取接收到的數據。更好用的是通過GetDataReader方法,直接能得到一個DataReader實例,這樣你就可以直接讀取需要的內容了。
不過呢,通過GetDataReader方法得到的DataReader對象不知道是不是經過特殊處理了,在讀取前不需要調用LoadAsync方法來加載數據了,GetDataReader方法返回的DataReader的UnconsumedBufferLength屬性默認就是大於0,即數據已自動加載到Reader中了,我們直接就可以讀了。
隨后,再看看如何實現廣播消息的發送端。
這個就更TNND簡單了,直接把消息發給255.255.255.255就行了,可以從IpAddress類的Broardcast字段得到。
using (DatagramSocket socket = new DatagramSocket()) { // 廣播地址 255.255.255.255 HostName broardaddr = new HostName(IPAddress.Broadcast.ToString()); IOutputStream outstream = await socket.GetOutputStreamAsync(broardaddr, "9000"); DataWriter writer = new DataWriter(outstream); // 設置編碼格式 writer.UnicodeEncoding = UnicodeEncoding.Utf8; // 處理字符串長度 uint len = writer.MeasureString(content); // 寫入長度 writer.WriteUInt32(len); // 寫入內容 writer.WriteString(content); // 提交 await writer.StoreAsync(); // 釋放 writer.Dispose(); }
實例化socket后,調用GetOutputStreamAsync方法,並指定目標地址和端口,就可以直接得到一個IOutputStream,表示輸出流,向這個流寫入數據就可以發送了。
可以通過DataWriter類來簡單完成,由於這里發的是字符串,長度不確定,故要先發送長度,再發內容,以便接收方可以確定內容長度。
測試的時候,最好多弄幾台設備來試,我就用筆記本、山寨板、手機三台設備來測試。哦,對了,在手機上運行很簡單,用USB連上,直接運行就可以了。平板上測試與遠程調試一樣,先在板子上安裝VS遠程調試工具,因為平板就是一台電腦,所以操作和遠程調試一樣。
以下是測試結果: