目標效果:實現Universal Windows Platform開發環境下的TCP連接
uwp用的庫跟.net庫不一樣,我主要用到網絡連接部分。.net下是system.net,uwp下是Windows.Networking.Sockets。具體的類也與之前很不同,廢了很大勁才算基本實現。
遇到的問題:
1. 開發環境的問題。在win10下用administrator賬戶登錄用vs2015開發uwp程序時,無法瀏覽設計器,而且無法運行,切換成普通用戶就沒問題。
2. uwp端斷開連接時服務端無限收到長度為0的信息傳入。問題的原因始終沒有找到,通過在服務端加上了判斷收到的信息是否長度為0來主動斷開tcp連接解決了。看網上有人說在同一個機器上進行UWPtcp調試時會有異常,不知道是不是這個。
1 int length = socket1.EndReceive(ar); 2 if(length<1) 3 { 4 socket1.Disconnect(false); 5 throw new Exception("遠程主機發來了為空的信息,連接已強行關閉!"); 6 }
3. 控件線程安全問題。要實現的功能為將服務器端接受到的信息顯示在窗體的textbox里。.net習慣用delegate和invoke來實現跨線程控制控件,Uwp下沒找到熟悉的invoke(也有這個關鍵字,但是沒弄明白怎么用),直接用textbox.text還是會引發異常。后來在qq群里面經人指點,使用了
CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, new Windows.UI.Core.DispatchedHandler(settext1));
解決了問題。PS:還有一個Window.Current.Dispatcher.RunAsync()說是能實現一樣的效果,不過實測是發生Window.Current為null的異常。所以推薦用CoreApplication。
4. 接受與發送使用DataReader和DataWriter,用起來還挺方便的。
發送的用法
byte[] data; DataWriter dw = new DataWriter(tcpsocket.OutputStream); data = Encoding.Unicode.GetBytes(textBox2.Text); dw.WriteBytes(data); await dw.StoreAsync(); dw.DetachStream(); dw.Dispose();
接受的用法
DataReader dr = new DataReader(tcpsocket.InputStream); dr.InputStreamOptions = InputStreamOptions.Partial; uint xx = await tcpinput.LoadAsync(1024); data = new byte[xx]; dr.ReadBytes(data); dr.DetachStream(); dr.Dispose();
5. 在unity3d中使用了queue來存儲傳來的信息,由於怕發生沖突在接受的異步操作中用了lock鎖,結果發生錯誤,后來取消了異步中的鎖,改在主線程的update函數中處理queue時使用lock。看來unity應該是不允許在非主線程中使用lock。