2009-05-03 59 views
0

我正在嘗試使用套接字編寫一個簡單的SNPP(簡單網絡分頁協議)客戶端。除了服務器之間的小差異外,一切似乎都運行良好。從Socket接收分塊數據到單個緩衝區

當我發送一個命令時,我需要讀取通常是單個數據塊的回覆。但是,Sprint的SNPP服務器分兩部分發送回復。第一個數據塊是狀態碼的第一個數字。第二塊是餘下的。例如,當我試圖收到「220網關準備好了」的答覆,它到達這樣的:

2 

我再派空命令檢索休息:

20 Gateway ready 

眼下,我使用的是:

byte[] buffer = new byte[256]; 
socket.Receive(buffer); 

我怎樣才能確保我收到的所有可用的數據,而不爲每個數據塊分配一個單獨的緩衝區發出命令後?

回答

3

分塊的回答,我建議你閱讀的數據是這樣的:

using (var resultStream = new MemoryStream()) 
{ 
    const int CHUNK_SIZE = 2 * 1024; // 2KB, could be anything that fits your needs 
    byte[] buffer = new byte[CHUNK_SIZE]; 
    int bytesReceived; 
    while ((bytesReceived = socket.Receive(buffer, buffer.Length, SocketFlags.None)) > 0) 
    { 
     byte[] actual = new byte[bytesReceived]; 
     Buffer.BlockCopy(buffer, 0, actual, 0, bytesReceived); 
     resultStream.Write(actual, 0, actual.Length); 
    } 

    // Do something with the resultStream, like resultStream.ToArray() ... 
} 
+0

我喜歡這個解決方案,因爲它處理所有大小的塊。但是,收到第一個答覆後,應用程序停止響應,直到有新數據。調試器顯示它掛起時的狀態。 – 2009-05-03 15:17:26

1

嘗試檢查Socket.Available屬性以確定是否需要再次調用接收。

0

我想我明白你的問題。 Socket.Receive的這個過載允許您傳遞一個整數來指定開始放置數據的偏移位置。如果你有1個字節,在你的例子中的第一個調用,你可以調用這個過載偏移量爲1,並使用相同的緩衝區。

0

Socket.Receive返回一個整數,即接收到的字節數。您可以檢查這是否爲1,並再次致電Receive

byte[] buffer = new byte[256]; 
int len = socket.Receive(buffer); 

if (len == 1) 
    socket.Receive(buffer, 1, buffer.Length - 1, SocketFlags.None); 
-1

所有,

當Web服務器在「塊」將數據發送它之前每一塊與它的長度(作爲表示十六進制值的字符串)。

塊大小[;塊的擴展] 塊數據

例如:以塊爲15個字節:

F; 123456789ABCDEF

從Socket接收HTTP數據的最大問題是確定要讀取多少數據:如果您已收到所有可用數據並再次調用Recieve方法,則Recieve方法將阻塞,直到遠程套接字發送更多的數據,這對HTTP/1.0連接永遠不會發生。

您需要實現一個包裹套接字的閱讀器;它應該接收數據到一個緩衝區,並提供一個「ReadLine」方法來讀取緩衝區的內容,直到它讀取13,然後是10(CRLF)

相關問題