1. 程式人生 > >Windows8 Metro界面下的StreamSocket 發送數據與接收數據

Windows8 Metro界面下的StreamSocket 發送數據與接收數據

系統 過程 bytes 一段時間 easy 鏈接 簡單 except nbsp

上次說了這麽用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 的做法,但是目前的問題被解決了。如果以後找到別的做法再做更新吧。

Windows8 Metro界面下的StreamSocket 發送數據與接收數據