2016-05-16 51 views
1

我正在使用StreamSocket連接到套接字服務器,並使用無限循環來讀取數據。每條數據以'\ n \ n'結尾。片段如下所示。但是,我不知道套接字是否仍然存在,並且每次服務器關閉連接時,ReadAsync()都會拋出異常。連接關閉時如何通知?如何知道在UWP中使用StreamSocket時套接字連接是否仍然存在?

public async Task<string> ReadData() { 
    StreamReader reader = new StreamReader(socket.InputStream.AsStreamForRead()); 
    char[] ch = new char[65536]; 
    int i = 0; 
    while (IsConnected) { 
     await reader.ReadAsync(ch, i++, 1); 
     if (i > 1 && ch[i - 1] == '\n' && ch[i - 2] == '\n') break; 
    } 
    return new StringBuilder().Append(ch, 0, i - 2).ToString(); 
} 

回答

0

,每次關閉服務器的連接,ReadAsync()拋出異常。

由於發生不合格斷開連接而引發異常。因此,確保有關閉服務器端的連接之前,沒有任何掛起的讀或寫操作存在於套接字上,那麼應該沒有異常。有關更多詳細信息,請參閱StreamSocket class的備註部分。

如何在連接關閉時通知?

優雅套接字可以被另一端檢測爲0長度讀取。也就是說,它只是像一個常規的流結束。 Here是一個類似的線程供您參考。

所以,你可以使用下面的代碼來檢查連接是否在您的情況關閉:

// break when the connection is closed 
if (ch[i - 1] == '\0') break; 

以下是整個方法我已經驗證:

public async Task<string> ReadData() 
{ 
    StreamReader reader = new StreamReader(socket.InputStream.AsStreamForRead()); 
    char[] ch = new char[65536]; 
    int i = 0; 
    while (true) 
    { 
     await reader.ReadAsync(ch, i++, 1); 
     // break when the connection is closed or data ends with '\n\n' 
     if (ch[i - 1] == '\0' || (i > 1 && ch[i - 1] == '\n' && ch[i - 2] == '\n')) break; 
    } 

    if (ch[i - 1] == '\0') 
    { 
     // do something here when the connection is closed 
    } 
    else 
    { 
     return new StringBuilder().Append(ch, 0, i - 2).ToString(); 
    } 
} 
0

每次服務器關閉連接,ReadAsync()拋出異常。

這是大多數服務器的預期。 TCP/IP有一個相當昂貴的四部分握手來優雅地關閉一個連接,但從服務器的角度來看,這是等待回收這些資源的很長一段時間。所以,很多服務器只是「關閉」連接關閉,導致SocketError.ConnectionReset錯誤。

正如我在我的socket error handling博客文章中所描述的那樣,如果通信狀態是這樣的,那麼您會認爲此時適當地「適度關閉」,那麼您應該同時接受ConnectionReset的例外。 (在你的情況下,如果消息已經填入\n\n),相應的「關閉」點。

如何在連接關閉時通知?

你要麼得到一個ConnectionReset異常(如果是突然關閉),或者你ReadAsync將返回0(如果是正常關閉)。

但是......

如何知道插座連接是否還活着?

只有一種可靠的方法來檢測套接字連接是否仍然是可行的:數據給它。我在我的博客文章half-open problem中詳細介紹了這一點。

由於套接字通信中的這個相當有趣的怪癖,類似while (IsConnected)這樣的代碼是一種反模式。相反,你需要有一個普通的輪詢循環,根據定時器將數據發送到另一端。

P.S.如果可能的話,使用SignalR代替原始套接字。他們爲你做了所有困難的事情。

相關問題