private bool FillBuffer(List <ArraySegment <byte> > buffer, int length) { var offset = 0; while (offset < length) { Socket socketCapture = null; if (Cts.IsCancellationRequested) { return(false); } try { if (gatewayConnection.Socket == null || !gatewayConnection.Socket.Connected) { gatewayConnection.Connect(); } socketCapture = gatewayConnection.Socket; if (socketCapture != null && socketCapture.Connected) { var bytesRead = socketCapture.Receive(ByteArrayBuilder.BuildSegmentList(buffer, offset)); if (bytesRead == 0) { throw new EndOfStreamException("Socket closed"); } offset += bytesRead; } } catch (Exception ex) { // Only try to reconnect if we're not shutting down if (Cts.IsCancellationRequested) { return(false); } if (ex is SocketException) { Log.Warn(ErrorCode.Runtime_Error_100158, "Exception receiving from gateway " + gatewayConnection.Address); } gatewayConnection.MarkAsDisconnected(socketCapture); return(false); } } return(true); }
// Builds the list of buffer segments to pass to Socket.BeginReceive, based on the total list (CurrentBuffer) // and how much we've already filled in (Offset). We have to do this because the scatter/gather variant of // the BeginReceive API doesn't allow you to specify an offset into the list of segments. // To build the list, we walk through the complete buffer, skipping segments that we've already filled up; // add the partial segment for whatever's left in the first unfilled buffer, and then add any remaining buffers. private List <ArraySegment <byte> > BuildSegmentList() { return(ByteArrayBuilder.BuildSegmentList(CurrentBuffer, offset)); }