现在的位置: 首页 > 综合 > 正文

吐槽Windows Phone 7的Socket类型

2012年04月28日 ⁄ 综合 ⁄ 共 2071字 ⁄ 字号 评论关闭

    Windows Phone 7的Socket类型修改自Silverlight中的Socket类型。总体来说,相比桌面完整.NET中的Socket类型,它的阉割程度相当大。

    首先所有操作只能是异步的,而且不同于传统Socket类型的APM异步方法(比如BeginConnect,BeginSend等),他使用了一种类似EAP的模式,典型的EAP模式异步调用比如是WebClient的DownloadStringAsync方法和它的DownloadStringCompleted事件。不过Windows Phone 7中的Socket类型本身没有定义任何事件,而是把事件定义在一个叫SocketAsyncEventArgs类型中。

    那么这种Socket类型的工作流程是这样的。首先初始化一个SocketAsyncEventArgs类型,设置相应的属性,比如如果进行连接操作,那么设置SocketAsyncEventArgs.RemoteEndPoint属性,如果想发送数据,需调用SocketAsyncEventArgs类型的SetBuffer方法设置内部Buffer。

    接下来,注册SocketAsyncEventArgs类型的Completed事件,因为Socket类型的所有操作都是异步的,因此必须注册这个事件从而获取异步操作的结果。Completed事件的委托类型是EventHandler<SocketAsyncEventArgs>,也就是说它会把自己作为EventArgs。

    最后,在Completed事件中,通过SocketAsyncEventArgs对象的一些属性来获取你需要的数据(感觉这样过分得使用一个EventArgs类型有些别扭)。比如SocketAsyncEventArgs.SocketError属性返回操作结果。如果你调用的是Socket.ReceiveAsync方法,你需要SocketAsyncEventArgs.Buffer属性。另外注意,如果SocketError等于Success的话,那么代表着操作成功。(什么?SocketError.Success?那还是Error吗?哈哈,我也不知道谁定义的它,也算另一个吐槽点吧)

 

来段演示代码吧,比如我们需要异步连接到远程,需要调用Socket.ConnectAsync方法,如下:

//创建SocketAsyncEventArgs

var socketArgs = new SocketAsyncEventArgs();

//设置连接的IP地址和端口号

socketArgs.RemoteEndPoint = new IPEndPoint(IPAddress.Parse("123.123.123.123"), 1033);

//注册Completed事件

socketArgs.Completed += socketArgs_Completed;

//开始操作

//socket变量是Socket对象

socket.ConnectAsync(socketArgs);

 

然后是Completed事件方法:

void socketArgs_Completed(object sender, SocketAsyncEventArgs e)

{

    //判断是否成功

    if (e.SocketError == SocketError.Success)

    {

        //获取远程连接IP和端口号(IPEndPoint对象)

        var endPoint = e.RemoteEndPoint;

    }

    else

    {

        //抛出SocketException

        throw new SocketException((int)e.SocketError);

    }

}

可以看到,在Completed事件中,上面代码会先判断SocketAsyncEventArgs.SocketError属性,如果不成功的话,抛出SocketException异常。

 

还有一些非常致命的问题,Windows Phone 7中的Socket没有任何TCP监听的方法。没有Listen没有Accept方法。同时SocketAsyncEventArgs类型中只有RemoteEndPoint属性而没有LocalEndPoint属性。太无奈了。不过好消息是Windows Phone 8和Windows 8中可以进行更完善的Socket操作了。

 

更新:

又写了一篇关于Windows Phone 7 Socket的文章:

在Windows Phone 7环境下执行NetworkStream类型

 

又发现一点,Socket.ConnectAsync貌似总会成功,即便是对应的RemoteEndPoint根本没有TCP监听,而且此时Socket的RemoteEndPoint和Connected都会是连接成功的结果,但实际上根本没有连接成功。等真正调用SendAsync后,才会返回SocketError.NotConnected。

抱歉!评论已关闭.