2015-07-21 84 views
0

我有一個套接字應用程序,連接到服務器,然後接收緩衝區(大小是已知的),但在慢速網絡應用程序不接收完整的緩衝區這裏是我的代碼套接字不讀所有的字節從服務器

var bytes = new byte[65000]; 
Socket.Receive(bytes); 
+2

您需要循環將其分塊。 –

+1

你是否檢查剩餘多少字節? – Gnqz

+2

'Socket.Receive'返回一個int,它是接收到的字節數。 –

回答

4

這是很容易的,你可以讓necesarry改變

private byte[] ReadBytes(int size) 
    { 
     //The size of the amount of bytes you want to recieve, eg 1024 
     var bytes = new byte[size]; 
     var total = 0; 
     do 
     { 
      var read = _connecter.Receive(bytes, total, size - total, SocketFlags.None); 
      Debug.WriteLine("Client recieved {0} bytes", total); 
      if (read == 0) 
      { 
       //If it gets here and you received 0 bytes it means that the Socket has Disconnected gracefully (without throwing exception) so you will need to handle that here 
      } 
      total+=read; 
      //If you have sent 1024 bytes and Receive only 512 then it wil continue to recieve in the correct index thus when total is equal to 1024 you will have recieved all the bytes 
     } while (total != size); 
     return bytes; 
    } 

爲了模擬這個我有一個生成以下出來投入到調試控制檯測試控制檯應用程序(有一些線程和睡眠)

Server Sent 100 bytes 
Server Sent 100 bytes 
Server Sent 100 bytes 
Server Sent 100 bytes 
Server Sent 100 bytes 
Server Sent 12 bytes 
Client Reads 512 bytes 
Client Recieved 100 bytes 
Client Recieved 200 bytes 
Client Recieved 300 bytes 
Client Recieved 400 bytes 
Client Recieved 500 bytes 
Client Recieved 512 bytes 

我有一個Android應用程序

+0

您的代碼在客戶端斷開的部分不正確。你需要將它分成兩個變量。一個用於「Receive」(例如'receivedBytes')和'total'的結果。您需要檢查receive'Bytes == 0',而不是'total == 0',因爲您可能在連接斷開之前收到數據。在這種情況下,'total!= 0'但是'receivedBytes == 0'。 –

+0

爲了清晰起見,我會交換變量「大小」和「總數」:-) –

+0

這樣的事情 ** var read = _connecter.Receive(bytes,total,size - total,SocketFlags。無); ** **如果(讀取== 0) { } ** **總計+ =讀取; ** – WhaChi

2

方法Socket.Receive將返回被讀取的有效字節數相同的問題。

由於Receive如果在一定時間內沒有接收到數據,您不能依賴緩衝區大小來獲取完整的緩衝區讀取。認爲65000作爲最大而不是有效緩衝區。

在快速網絡上,您將得到buffer以快速填充,但是在網絡緩慢的情況下,數據包延遲將觸發Receive將自己刷新到緩衝區陣列。

爲了讀取固定大小的緩衝區可能想做的事:

public static byte[] ReadFixed (Socket this, int bufferSize) { 
    byte[] ret = new byte[bufferSize]; 
    for (int read = 0; read < bufferSize; read += this.Receive(ret, read, ret.Size-read, SocketFlags.None)); 
    return ret; 
} 

以上的創建作爲一個擴展的方法來Socket類使用更安心。代碼是手寫的。

0

這種方式不需要設置初始讀取大小,它適合於響應。

public static byte[] ReceiveAll(this Socket socket) 
{ 
    var buffer = new List<byte>(); 

    while (socket.Available > 0) 
    { 
     var currByte = new Byte[1]; 
     var byteCounter = socket.Receive(currByte, currByte.Length, SocketFlags.None); 

     if (byteCounter.Equals(1)) 
     { 
      buffer.Add(currByte[0]); 
     } 
    } 

    return buffer.ToArray(); 
}