public void AppendIncoming(NetContext context, byte[] buffer, int index, int count) { if(count != 0) { if (incomingBuffer == null) incomingBuffer = new BufferStream(context, context.Handler.MaxIncomingQuota); incomingBuffer.Position = incomingBuffer.Length; incomingBuffer.Write(buffer, index, count); } }
public void DisableRead() { if(CanRead) { SetFlag(ConnectionFlags.CanRead, false); var socket = Socket; if(incomingBuffer != null) { incomingBuffer.Dispose(); incomingBuffer = null; } if(socket != null) { socket.Shutdown(SocketShutdown.Receive); } } }
public bool ProcessBufferedData(NetContext context, out int messageCount) { messageCount = 0; if (incomingBuffer != null && incomingBuffer.Length > 0) { int toDiscard; do { if (!CanRead) break; // stop processing data #if VERBOSE long inboundLength = incomingBuffer.Length; Debug.WriteLine(string.Format("[{0}]\tprocessing with {1} bytes available", context.Handler, inboundLength)); #endif incomingBuffer.Position = 0; toDiscard = protocol.ProcessIncoming(context, this, incomingBuffer); if (toDiscard > 0) { messageCount++; // could be null if our processing shut it down! if(incomingBuffer != null) { if(toDiscard == incomingBuffer.Length) { incomingBuffer.Dispose(); incomingBuffer = null; } else { incomingBuffer.Discard(toDiscard); } } #if VERBOSE Debug.WriteLine(string.Format("[{0}]\tprocessed {1} bytes; {2} remaining", context.Handler, toDiscard, inboundLength - toDiscard)); #endif } else if(toDiscard < 0) { if(incomingBuffer != null) { incomingBuffer.Dispose(); incomingBuffer = null; } // stop reading! (for example, protocol error, graceful shutdown) return false; } else { #if VERBOSE Debug.WriteLine(string.Format("[{0}]\tincomplete", context.Handler)); #endif } } while (toDiscard > 0 && incomingBuffer != null && incomingBuffer.Length > 0); } if(incomingBuffer != null && incomingBuffer.Length == 0) { incomingBuffer.Dispose(); incomingBuffer = null; } return true; }
public int ReadOutgoing(NetContext context, byte[] buffer, int index, int count) { int bufferedLength = outgoingBuffer == null ? 0 : (int) outgoingBuffer.Length; if (bufferedLength == 0) { // nothing in the outbound buffer? then check to see if we have any new messages needing processing at the protocol layer, then the connection/handler layer IFrame frame; const int SANE_PACKET_SIZE = 512; while (bufferedLength < SANE_PACKET_SIZE && ((frame = protocol.GetOutboundFrame(context)) != null || (context.Handler.RequestOutgoing(this) && (frame = protocol.GetOutboundFrame(context)) != null)) && GetFlag(ConnectionFlags.IsAlive)) // ^^^^ we try and get a frame from the protocol layer; if that is empty, we nudge the connection/handler layer to write, and then we // check again for a fram from the protocol layer (the connection/handler can only queue frames); we then repeat this if necessary/appropriate // to fill a packet { if (outgoingBuffer == null) outgoingBuffer = new BufferStream(context, context.Handler.MaxOutgoingQuota); outgoingBuffer.Position = outgoingBuffer.Length; outgoingBuffer.IsReadonly = false; frame.Write(context, this, outgoingBuffer); outgoingBuffer.IsReadonly = true; bufferedLength = (int) outgoingBuffer.Length; if (frame.Flush) break; // send "as is" } } if (bufferedLength == 0) { Interlocked.Exchange(ref writerCount, 0); // nix and nada return 0; } int bytesRead = 0; if (outgoingBuffer != null) { outgoingBuffer.Position = 0; bytesRead = outgoingBuffer.Read(buffer, index, count); outgoingBuffer.Discard(bytesRead); if(outgoingBuffer.Length == 0) { outgoingBuffer.Dispose(); outgoingBuffer = null; } } return bytesRead; }