Windows8 Metro界面下的StreamSocket 发送数据与接收数据

上次说了这么用StreamSocket来建立连接,现在看看怎么用StreamSocket发送和接收数据。

首先我们知道StreamSocket实例中有InputStream 和 OutputStream 这两个属性,看名字就知道我们接下来的操作一定与它离不开关系了。
那么先说发送,发送数据时我们将会用到 Windows.Storage.Streams.DataWriter 来帮助我们方便的吧数据发送出去,当然这个操作也和链接一样是异步的。
首先需要从已经建立好连接的 StreamSocke t实例中利用 OutputStream 熟悉实例化一个DataWriter
var writer = new DataWriter(_socket.OutputStream);

 然后就可以利用 DataWriter 向服务器传输各种类型的数据了,这里他提供了好多数据类型,我就选择Byte做示范吧,代码如下:

var buffer = new List<byte>();
buffer.AddRange(BitConverter.GetBytes(123));

try
{
    var writer = new DataWriter(_socket.OutputStream);

    //将数据写入到输出流中
    writer.WriteBytes(buffer.ToArray());
    //将数据提交到备份存储区(这里不是直接发送数据而是放到了备份存储区,我的理解可能是会当前不能发送数据或者其他情况下放置一段时间,等待能够发送出去时才真正发送数据,这个发送过程是由系统自动管理的)
    await writer.StoreAsync();
}
catch(Exception)
{ 
    //这里做异常处理,比如发送失败的原因判断
}
那么这样就可以正常发送数据了。
接下来是接收服务器发来的信息,接收服务器发来的信息与以前的Socket 监听方法同样是一次性执行的,使用DataReader对象进行数据读取,下面是官方的Demo中的代码:
uint stringLength = reader.ReadUInt32(); //读取包头的最前面4个字节,这里是协议中有描述包有多长,不是真正的包的长度
uint actualStringLength = await reader.LoadAsync(stringLength); 
if (stringLength != actualStringLength) 
{ 
    // 如果包头描述的长度与接收到的长度不一致则表示对方过早断开连接,包不可用 
    return; 
}

string data = reader.ReadString(actualStringLength);

 

那么我的要做的是持续的监听从服务端发送过来的数据,那么很简单,用死循环制造一个不停监听的线程,刚好我们的方法是一个异步方法,省去了对线程的管理使其变的很简单。代码如下:

private async void Listen()
{
    Stream stream = _socket.InputStream.AsStreamForRead(1024);
    byte[] buffer = new byte[1024];

    while (true)
    {
        int len = stream.Read(buffer, 0, buffer.Length);//这个方法会等待有数据从服务器发送过来后才执行后续代码
        if (len == 0)
        {//接收长度为0这表示断开连接
            return;
        }

        try
        {
            //数据处理逻辑
        }
        catch (ObjectDisposedException ex)
        {
            Logger.Log.Warn(ex);
            Close();
            return;
        }
    }
}

不过我总觉得这种做法有点不符合StreamSocket 的做法,但是目前的问题被解决了。如果以后找到别的做法再做更新吧。

posted @ 2013-01-07 16:51  安培昌浩  阅读(192)  评论(0编辑  收藏  举报