2016-04-27 23 views
0

Hier ist mein Code, den ich mit einem Problem habe:C# Sockel Empfangen: Taking in Daten, bis Puffer voll Dilemma

// read the file in chunks of 5KB 
var buffer = new byte[1024*5]; 
int bytesRead = 0; 
do 
{ 
    bytesRead = host.Receive(buffer, buffer.Length, 0); 
    output.Write(buffer, 0, bytesRead); 
} 
while (bytesRead == buffer.Length); 

Also hier ist mein Problem: Ich, solange die Puffer in Daten lesen will ist voll. Auch wenn mehr Daten vorhanden sind, wird der Puffer beim Senden nicht garantiert. Dies führt dazu, dass der Empfang vorzeitig beendet wird. Wenn ich die While-Bedingung zu ändere, dann erreicht es das Ende der Daten und Receive-Blöcke, bis mehr Daten verfügbar sind (was nicht sein wird). Wie löse ich das?

+0

_ "und Empfangen von Blöcken bis ..." _ - warum? Weil es nicht sollte. –

+0

Wie Henk sagte "es sollte nicht". Wenn Sie das Ende der Daten erreichen, lesen Sie nicht mehr, also sollten Sie nicht mehr versuchen zu lesen? Ich denke, du musst mehr klären, was du meinst. Warum möchten Sie weiterlesen, wenn keine Daten mehr vorhanden sind? – MrApnea

+0

@FSDaniel Ich nicht. Laut MDSN blockiert der Socket.Receive-Aufruf jedoch, wenn keine Daten mehr vorhanden sind. Gibt es einen Weg dahin? Ich weiß, dass ich eine Zeitüberschreitung machen kann, aber das wird nicht bei jeder Übertragung funktionieren. – blurbs78

Antwort

0

Ich denke, Sie müssen darüber nachdenken, wie das Protokoll funktioniert und eine robustere Lösung machen. Entweder gehst du mit blocking und dann kannst du entweder warten bis du keine Daten mehr zu lesen hast und dann etwas anderes machen und wieder lesen wenn du weißt dass du mehr Daten zum lesen hast.

Oder Sie fügen Threading und haben einen separaten Thread, der nur liest, und dann ist es egal, wenn es blockiert, da es auf einem separaten Thread sein wird.

Eine andere Lösung, die einfacher sein könnte, ist die Verwendung asynchroner Lesevorgänge.

können Sie hier mehr darüber lesen: https://msdn.microsoft.com/en-us/library/bbx2eya8(v=vs.110).aspx

Ein einfaches Beispiel von der Website oben mit dem Lesen zu beginnen ist:

private static void Receive(Socket client) { 
    try { 
     // Create the state object. 
     StateObject state = new StateObject(); 
     state.workSocket = client; 

     // Begin receiving the data from the remote device. 
     client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, 
      new AsyncCallback(ReceiveCallback), state); 
    } catch (Exception e) { 
     Console.WriteLine(e.ToString()); 
    } 
} 

Dann werden Sie einen Rückruf erhalten ReceiveCallback wenn es Daten gibt, behandelt werden:

private static void ReceiveCallback(IAsyncResult ar) { 
    try { 
     // Retrieve the state object and the client socket 
     // from the asynchronous state object. 
     StateObject state = (StateObject) ar.AsyncState; 
     Socket client = state.workSocket; 
     // Read data from the remote device. 
     int bytesRead = client.EndReceive(ar); 
     if (bytesRead > 0) { 
      // There might be more data, so store the data received so far. 
      state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead)); 
       // Get the rest of the data. 
      client.BeginReceive(state.buffer,0,StateObject.BufferSize,0, 
       new AsyncCallback(ReceiveCallback), state); 
     } else { 
      // All the data has arrived; put it in response. 
      if (state.sb.Length > 1) { 
       response = state.sb.ToString(); 
      } 
      // Signal that all bytes have been received. 
      receiveDone.Set(); 
     } 
    } catch (Exception e) { 
     Console.WriteLine(e.ToString()); 
    } 
} 

ich hoffe, das funktioniert, wenn wir nicht wissen müssen, um mehr über welches Protokoll Sie verwenden, und wenn es aus irgendeinem Grund Sie bl brauchen ocking liest, damit wir genauere Informationen und Hilfe geben können.