目标效果:实现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。