// Performs a single blocking read to the netstack, and adds data // to dataBuffer. // Returns true if future read operations are permissible; false // if the data stream has ended. private bool BlockingRead(TcpConnectionContract /*.Imp*/ conn, TrackedBytesBuffer dataBuffer) { Bytes readData = conn.Read(); //case conn.Data(byte[] readData) : if (readData != null) { // Tack this onto the data buffer. Data is consumed by AddToTail. dataBuffer.AddToTail(readData); return(true); } //case conn.NoMoreData() : //case conn.ConnectionClosed() : return(false); }
// Reads as much as possible without blocking, tack it onto dataBuffer. // We will block for a MAXIMUM of the time specified by "microSeconds". // Returns true if future read operations are permissible, false if // the data stream has ended private bool DrainDataNonBlock(TcpConnectionContract /*.Imp*/ conn, TrackedBytesBuffer dataBuffer, int microSeconds) { bool keepTrying = true; int timeToSleep = microSeconds; while (keepTrying) { keepTrying = false; // defensive Bytes readData = conn.PollRead(timeToSleep); //case conn.Data(byte[] readData) : if (readData != null && readData.Length > 0) { // Tack this onto the data buffer. Data is consumed by AddToTail() dataBuffer.AddToTail(readData); // Keep trying, but don't sleep. We do this strictly to // drain off any additional data, since currently the // netStack hands data to us in packet-sized chunks, // which means it may have additional data ready if you // ask it again. keepTrying = true; timeToSleep = 0; continue; } //case conn.NoData() : if (readData != null && readData.Length == 0) { // done return(true); } //case conn.NoMoreData() : //case conn.ConnectionClosed() : if (readData == null) { return(false); } } // Should never get here return(true); }