/// <summary> /// We've received bytes from the socket. Build a message out of them. /// </summary> /// <param name="buffer">Buffer</param> /// <remarks></remarks> public void ProcessReadBytes(ISocketBuffer buffer) { var offsetInSocketBuffer = buffer.Offset; var bytesLeftInSocketBuffer = buffer.BytesTransferred; while (bytesLeftInSocketBuffer > 0) { var len = Math.Min(bytesLeftInSocketBuffer, _bytesLeftForCurrentMsg); Buffer.BlockCopy(buffer.Buffer, offsetInSocketBuffer, _buffer, _offsetInOurBuffer, buffer.BytesTransferred); offsetInSocketBuffer += len; bytesLeftInSocketBuffer -= len; _bytesLeftForCurrentMsg -= len; _offsetInOurBuffer += len; if (_bytesLeftForCurrentMsg != 0) continue; if (_readHeader) { _offsetInOurBuffer = 0; _msgLength = _bytesLeftForCurrentMsg = BitConverter.ToInt32(_buffer, 0); _readHeader = false; } else { _readHeader = true; _bytesLeftForCurrentMsg = 4; MessageReceived(Encoding.GetString(_buffer, 0, _msgLength)); } } }
/// <summary> /// We've received bytes from the socket. Build a message out of them. /// </summary> /// <param name="buffer">Buffer</param> /// <remarks></remarks> public void ProcessReadBytes(ISocketBuffer buffer) { var offsetInSocketBuffer = buffer.Offset; var bytesLeftInSocketBuffer = buffer.BytesTransferred; while (bytesLeftInSocketBuffer > 0) { var len = Math.Min(bytesLeftInSocketBuffer, _bytesLeftForCurrentMsg); Buffer.BlockCopy(buffer.Buffer, offsetInSocketBuffer, _buffer, _offsetInOurBuffer, buffer.BytesTransferred); offsetInSocketBuffer += len; bytesLeftInSocketBuffer -= len; _bytesLeftForCurrentMsg -= len; _offsetInOurBuffer += len; if (_bytesLeftForCurrentMsg != 0) { continue; } if (_readHeader) { _offsetInOurBuffer = 0; _msgLength = _bytesLeftForCurrentMsg = BitConverter.ToInt32(_buffer, 0); _readHeader = false; } else { _readHeader = true; _bytesLeftForCurrentMsg = 4; MessageReceived(Encoding.GetString(_buffer, 0, _msgLength)); } } }
public void Send(ISocketBuffer args) { if (_bytesTransferred < _bytesEnqueued) { //TODO: Is this faster than moving the bytes to the beginning of the buffer and append more bytes? args.SetBuffer(_bufferSlice.Buffer, _bufferSlice.Offset + _bytesTransferred, _bytesEnqueued - _bytesTransferred); return; } if (!_headerIsSent) { var headerLength = CreateHeader(); var bytesToWrite = (int)Math.Min(_bufferSlice.Capacity - headerLength, _bodyStream.Length); _bodyStream.Read(_bufferSlice.Buffer, _bufferSlice.Offset + headerLength, bytesToWrite); args.SetBuffer(_bufferSlice.Buffer, _bufferSlice.Offset, bytesToWrite + headerLength); _bytesEnqueued = headerLength + bytesToWrite; _bytesLeftToSend = headerLength + (int)_bodyStream.Length; } else { _bytesEnqueued = (int)Math.Min(_bufferSlice.Capacity, _bytesLeftToSend); _bodyStream.Write(_bufferSlice.Buffer, _bufferSlice.Offset, _bytesEnqueued); args.SetBuffer(_bufferSlice.Buffer, _bufferSlice.Offset, _bytesEnqueued); } }
/// <summary> /// Serialize message and sent it add it to the buffer /// </summary> /// <param name="args">Socket buffer</param> public void Send(ISocketBuffer args) { if (_bytesTransferred < _bytesEnqueued) { //TODO: Is this faster than moving the bytes to the beginning of the buffer and append more bytes? args.SetBuffer(_bufferSlice.Buffer, _bufferSlice.Offset + _bytesTransferred, _bytesEnqueued - _bytesTransferred); return; } if (!_headerIsSent) { var headerLength = CreateHeader(); var bytesToWrite = (int)Math.Min(_bufferSlice.Capacity - headerLength, _bodyStream.Length); _bodyStream.Read(_bufferSlice.Buffer, _bufferSlice.Offset + headerLength, bytesToWrite); args.SetBuffer(_bufferSlice.Buffer, _bufferSlice.Offset, bytesToWrite + headerLength); _bytesEnqueued = headerLength + bytesToWrite; _bytesLeftToSend = headerLength + (int)_bodyStream.Length; } else { _bytesEnqueued = Math.Min(_bufferSlice.Capacity, _bytesLeftToSend); _bodyStream.Read(_bufferSlice.Buffer, _bufferSlice.Offset, _bytesEnqueued); args.SetBuffer(_bufferSlice.Buffer, _bufferSlice.Offset, _bytesEnqueued); } }
/// <summary> /// We've received bytes from the socket. Build a message out of them. /// </summary> /// <param name="buffer">Buffer</param> /// <remarks></remarks> public void ProcessReadBytes(ISocketBuffer buffer) { int receiveBufferOffset = buffer.Offset; int bytesLeftInReceiveBuffer = buffer.BytesTransferred; while (true) { if (bytesLeftInReceiveBuffer <= 0) break; if (!_isHeaderParsed) { var offsetBefore = receiveBufferOffset; receiveBufferOffset = _headerParser.Parse(buffer, receiveBufferOffset); if (!_isHeaderParsed) return; bytesLeftInReceiveBuffer -= receiveBufferOffset - offsetBefore; _frameContentBytesLeft = _frame.ContentLength; if (_frameContentBytesLeft == 0) { // the NULL message delimiter if (bytesLeftInReceiveBuffer == 1) bytesLeftInReceiveBuffer = 0; MessageReceived(_frame); _frame = null; _isHeaderParsed = false; continue; } _frame.Body = new MemoryStream(); } var bytesRead = BytesProcessed(buffer.Offset, receiveBufferOffset); var bytesToWrite = Math.Min(_frameContentBytesLeft, buffer.BytesTransferred - bytesRead); _frame.Body.Write(buffer.Buffer, receiveBufferOffset, bytesToWrite); _frameContentBytesLeft -= bytesToWrite; receiveBufferOffset += bytesToWrite; bytesLeftInReceiveBuffer -= bytesToWrite; bytesRead += bytesToWrite; if (_frameContentBytesLeft == 0) { // ignore NULL (message delimiter) //TODO: Maybe verify it? ;) var bytesRemaining = buffer.BytesTransferred - bytesRead; if (bytesRemaining == 1) { bytesLeftInReceiveBuffer--; receiveBufferOffset++; } _frame.Body.Position = 0; MessageReceived(_frame); Clear(); } } }
/// <summary> /// We've received bytes from the socket. Build a message out of them. /// </summary> /// <param name="buffer">Buffer</param> public void ProcessReadBytes(ISocketBuffer buffer) { var receiveBufferOffset = buffer.Offset; var bytesLeftInReceiveBuffer = buffer.BytesTransferred; while (true) { if (bytesLeftInReceiveBuffer <= 0) { break; } if (!_isHeaderParsed) { var offsetBefore = receiveBufferOffset; receiveBufferOffset = _headerParser.Parse(buffer, receiveBufferOffset); if (!_isHeaderParsed) { return; } if (_message == null) { throw new HttpException(HttpStatusCode.InternalServerError, "Failed to decode message properly. Decoder state: " + _headerParser.State); } bytesLeftInReceiveBuffer -= receiveBufferOffset - offsetBefore; _frameContentBytesLeft = _message.ContentLength; if (_frameContentBytesLeft == 0) { TriggerMessageReceived(_message); _message = null; _isHeaderParsed = false; continue; } if (_message == null) { throw new HttpException(HttpStatusCode.InternalServerError, "Failed to decode message properly. Decoder state: " + _headerParser.State); } _message.Body = new MemoryStream(); } var bytesRead = BytesProcessed(buffer.Offset, receiveBufferOffset); var bytesToWrite = Math.Min(_frameContentBytesLeft, buffer.BytesTransferred - bytesRead); _message.Body.Write(buffer.Buffer, receiveBufferOffset, bytesToWrite); _frameContentBytesLeft -= bytesToWrite; receiveBufferOffset += bytesToWrite; bytesLeftInReceiveBuffer -= bytesToWrite; if (_frameContentBytesLeft == 0) { _message.Body.Position = 0; TriggerMessageReceived(_message); Clear(); } } }
/// <summary> /// Process bytes that we've received on the socket. /// </summary> /// <param name="buffer">Buffer to process.</param> public void ProcessReadBytes(ISocketBuffer buffer) { _bytesLeftInSocketBuffer = buffer.BytesTransferred; _socketBufferOffset = buffer.Offset; while (_stateMethod(buffer)) { } }
public bool ReadHeaderLength(ISocketBuffer e) { if (!CopyBytes(e)) return false; _headerSize = BitConverter.ToInt16(_header, 0); _bytesLeftForCurrentState = _headerSize; _stateMethod = ProcessFixedHeader; _headerOffset = 0; return true; }
private int AuthenticateBytes(ITcpChannel channel, ISocketBuffer buffer) { bool completed; var bytesProcessed = Authenticator.Process(channel, buffer, out completed); if (completed) { channel.BufferPreProcessor = null; } return(bytesProcessed); }
private bool ReadHeaderLength(ISocketBuffer e) { if (!CopyBytes(e)) { return(false); } _headerSize = BitConverter.ToInt16(_header, 0); _bytesLeftForCurrentState = _headerSize; _stateMethod = ProcessFixedHeader; _headerOffset = 0; return(true); }
/// <summary> /// Buffer structure used for socket send operations. /// </summary> /// <param name="buffer"> /// Do note that there are not buffer attached to the structure, you have to assign one yourself using /// <see cref="ISocketBuffer.SetBuffer(int,int)" />. This choice was made /// to prevent unnecessary copy operations. /// </param> public void Send(ISocketBuffer buffer) { // last send operation did not send all bytes enqueued in the buffer // so let's just continue until doing next message if (_bytesToSend > 0) { buffer.SetBuffer(_buffer, _offset, _bytesToSend); return; } // continuing with the message body if (_isHeaderSent) { var bytes = Math.Min(_totalAmountToSend, _buffer.Length); _message.Body.Read(_buffer, 0, bytes); _bytesToSend = bytes; buffer.SetBuffer(_buffer, 0, bytes); return; } _writer.WriteLine(_message.StatusLine); foreach (var header in _message.Headers) { _writer.Write("{0}: {1}\r\n", header.Key, header.Value); } _writer.Write("\r\n"); _writer.Flush(); _isHeaderSent = true; buffer.UserToken = _message; if (_message.Body == null || _message.ContentLength == 0) { _bytesToSend = (int)_stream.Length; _totalAmountToSend = _bytesToSend; buffer.SetBuffer(_buffer, 0, (int)_stream.Length); return; } else { } var bytesLeft = _buffer.Length - _stream.Length; var bytesToSend = Math.Min(_message.ContentLength, (int)bytesLeft); var offset = (int)_stream.Position; _message.Body.Read(_buffer, offset, bytesToSend); _bytesToSend = (int)_stream.Length + bytesToSend; _totalAmountToSend = (int)_stream.Length + _message.ContentLength; buffer.SetBuffer(_buffer, 0, _bytesToSend); }
/// <summary> /// Buffer structure used for socket send operations. /// </summary> /// <param name="buffer"> /// Do note that there are not buffer attached to the structure, you have to assign one yourself using /// <see cref="ISocketBuffer.SetBuffer(int,int)" />. This choice was made /// to prevent unnecessary copy operations. /// </param> public void Send(ISocketBuffer buffer) { // last send operation did not send all bytes enqueued in the buffer // so let's just continue until doing next message if (_bytesToSend > 0) { buffer.SetBuffer(_buffer, _offset, _bytesToSend); return; } // continuing with the message body if (_isHeaderSent) { var bytes = Math.Min(_totalAmountToSend, _buffer.Length); _message.Body.Read(_buffer, 0, bytes); _bytesToSend = bytes; buffer.SetBuffer(_buffer, 0, bytes); return; } _writer.WriteLine(_message.StatusLine); foreach (var header in _message.Headers) { _writer.Write("{0}: {1}\r\n", header.Key, header.Value); } _writer.Write("\r\n"); _writer.Flush(); _isHeaderSent = true; buffer.UserToken = _message; if (_message.Body == null || _message.ContentLength == 0) { _bytesToSend = (int) _stream.Length; _totalAmountToSend = _bytesToSend; buffer.SetBuffer(_buffer, 0, (int) _stream.Length); return; } else { } var bytesLeft = _buffer.Length - _stream.Length; var bytesToSend = Math.Min(_message.ContentLength, (int) bytesLeft); var offset = (int) _stream.Position; _message.Body.Read(_buffer, offset, bytesToSend); _bytesToSend = (int) _stream.Length + bytesToSend; _totalAmountToSend = (int) _stream.Length + _message.ContentLength; buffer.SetBuffer(_buffer, 0, _bytesToSend); }
/// <summary> /// Will try to parse everything in the buffer /// </summary> /// <param name="buffer">Buffer to read from.</param> /// <param name="offset">offset where the parser ended.</param> /// <remarks> /// <para> /// Do note that the parser is for the header only. The <see cref="Completed" /> event will /// indicate that there might be body bytes left in the buffer. You have to handle them by yourself. /// </para> /// </remarks> public int Parse(ISocketBuffer buffer, int offset) { int theByte; while ((theByte = Read(buffer, ref offset)) != -1) { var ch = (char) theByte; _parserMethod(ch); if (_isCompleted) break; } _isCompleted = false; return offset; }
private int Read(ISocketBuffer buffer, ref int offset) { if (_lookAhead != -1) { var tmp = _lookAhead; _lookAhead = -1; return tmp; } if (offset - buffer.BaseOffset >= buffer.BytesTransferred) return -1; return buffer.Buffer[offset++]; }
/// <summary> /// We've received bytes from the socket. Build a message out of them. /// </summary> /// <param name="buffer">Buffer</param> public void ProcessReadBytes(ISocketBuffer buffer) { var receiveBufferOffset = buffer.Offset; var bytesLeftInReceiveBuffer = buffer.BytesTransferred; while (true) { if (bytesLeftInReceiveBuffer <= 0) break; if (!_isHeaderParsed) { var offsetBefore = receiveBufferOffset; receiveBufferOffset = _headerParser.Parse(buffer, receiveBufferOffset); if (!_isHeaderParsed) return; if (_message == null) throw new HttpException(HttpStatusCode.InternalServerError, "Failed to decode message properly. Decoder state: " + _headerParser.State); bytesLeftInReceiveBuffer -= receiveBufferOffset - offsetBefore; _frameContentBytesLeft = _message.ContentLength; if (_frameContentBytesLeft == 0) { TriggerMessageReceived(_message); _message = null; _isHeaderParsed = false; continue; } if (_message == null) throw new HttpException(HttpStatusCode.InternalServerError, "Failed to decode message properly. Decoder state: " + _headerParser.State); _message.Body = new MemoryStream(); } var bytesRead = BytesProcessed(buffer.Offset, receiveBufferOffset); var bytesToWrite = Math.Min(_frameContentBytesLeft, buffer.BytesTransferred - bytesRead); _message.Body.Write(buffer.Buffer, receiveBufferOffset, bytesToWrite); _frameContentBytesLeft -= bytesToWrite; receiveBufferOffset += bytesToWrite; bytesLeftInReceiveBuffer -= bytesToWrite; if (_frameContentBytesLeft == 0) { _message.Body.Position = 0; TriggerMessageReceived(_message); Clear(); } } }
private int Read(ISocketBuffer buffer, ref int offset) { if (_lookAhead != -1) { var tmp = _lookAhead; _lookAhead = -1; return(tmp); } if (offset - buffer.BaseOffset >= buffer.BytesTransferred) { return(-1); } return(buffer.Buffer[offset++]); }
/// <summary> /// Will try to parse everything in the buffer /// </summary> /// <param name="buffer">Buffer to read from.</param> /// <param name="offset">Where to start parsing in the buffer.</param> /// <returns>offset where the parser ended.</returns> /// <remarks> /// <para> /// Do note that the parser is for the header only. The <see cref="Completed" /> event will /// indicate that there might be body bytes left in the buffer. You have to handle them by yourself. /// </para> /// </remarks> public int Parse(ISocketBuffer buffer, int offset) { int theByte; while ((theByte = Read(buffer, ref offset)) != -1) { var ch = (char)theByte; _parserMethod(ch); if (_isCompleted) { break; } } _isCompleted = false; return(offset); }
/// <summary> /// Buffer structure used for socket send operations. /// </summary> /// <param name="buffer"> /// Do note that there are not buffer attached to the structure, you have to assign one yourself using /// <see cref="ISocketBuffer.SetBuffer" />. This choice was made /// to prevent unnecessary copy operations. /// </param> public void Send(ISocketBuffer buffer) { if (_bytesToSend > 0) { buffer.SetBuffer(_buffer, _offset, _bytesToSend); return; } if (_isHeaderSent) { var bytes = Math.Min(_totalAmountToSend, _buffer.Length); _message.Body.Read(_buffer, 0, bytes); _bytesToSend = bytes; buffer.SetBuffer(_buffer, 0, bytes); return; } _writer.WriteLine(_message.StatusLine); foreach (var header in _message.Headers) { _writer.Write("{0}:{1}\r\n", header.Key, header.Value); } _writer.Write("\r\n"); _writer.Flush(); _isHeaderSent = true; if (_message.Body == null || _message.ContentLength == 0) { _bytesToSend = (int) _stream.Length; _totalAmountToSend = _bytesToSend; buffer.SetBuffer(_buffer, 0, (int) _stream.Length); return; } var bytesLeft = _buffer.Length - _stream.Length; var bytesToSend = Math.Min(_message.ContentLength, (int) bytesLeft); var offset = (int) _stream.Position; _message.Body.Read(_buffer, offset, bytesToSend); _bytesToSend = (int) _stream.Length + bytesToSend; _totalAmountToSend = (int) _stream.Length + _message.ContentLength; buffer.SetBuffer(_buffer, 0, _totalAmountToSend); }
public void Send(ISocketBuffer buffer) { this.stream.Position = 0; this.stream.SetLength(0); if (!this.isHeaderSent) { this.writer.WriteLine(this.response.StatusLine); foreach (var header in this.response.Headers) { if (string.IsNullOrEmpty(header.Key)) { continue; } this.writer.Write("{0}: {1}\r\n", header.Key, header.Value); } this.writer.Write("\r\n"); this.isHeaderSent = true; buffer.UserToken = this.response; this.writer.Flush(); } //stopwatch.Stop(); //Debug.WriteLine("Network: " + stopwatch.ElapsedMilliseconds); //stopwatch.Restart(); this.nextFrameAvailable = this.response.StreamSource.WriteNextFrame(this.multipartStream).Result; //stopwatch.Stop(); //Debug.WriteLine("Encoding: " + stopwatch.ElapsedMilliseconds); //stopwatch.Restart(); // Send buffer.SetBuffer(this.buffer, 0, (int)this.stream.Length); }
private bool ProcessFixedHeader(ISocketBuffer e) { if (!CopyBytes(e)) { return(false); } _protocolVersion = _header[0]; _contentLength = BitConverter.ToInt32(_header, 1); _typeLength = _header[5]; _contentName = Encoding.ASCII.GetString(_header, 6, _typeLength); _stateMethod = ProcessContent; _bytesLeftForCurrentState = _contentLength; _headerOffset = 0; _contentStream.SetLength(0); _contentStream.Position = 0; return(true); }
private bool CopyBytes(ISocketBuffer e) { if (_bytesLeftInSocketBuffer == 0) { return(false); } if (_bytesLeftForCurrentState > 0) { var toCopy = Math.Min(_bytesLeftForCurrentState, _bytesLeftInSocketBuffer); Buffer.BlockCopy(e.Buffer, _socketBufferOffset, _header, _headerOffset, toCopy); _headerOffset += toCopy; _bytesLeftForCurrentState -= toCopy; _bytesLeftInSocketBuffer -= toCopy; _socketBufferOffset += toCopy; } return(_bytesLeftForCurrentState == 0); }
/// <summary> /// We've received bytes from the socket. Build a message out of them. /// </summary> /// <param name="buffer">Buffer</param> public void ProcessReadBytes(ISocketBuffer buffer) { var receiveBufferOffset = buffer.Offset; var bytesLeftInReceiveBuffer = buffer.BytesTransferred; while (true) { if (bytesLeftInReceiveBuffer <= 0) break; if (!_isHeaderParsed) { var offsetBefore = receiveBufferOffset; receiveBufferOffset = _headerParser.Parse(buffer, receiveBufferOffset); if (!_isHeaderParsed) return; bytesLeftInReceiveBuffer -= receiveBufferOffset - offsetBefore; _frameContentBytesLeft = _message.ContentLength; if (_frameContentBytesLeft == 0) { TriggerMessageReceived(_message); _message = null; _isHeaderParsed = false; continue; } _message.Body = new MemoryStream(); } var bytesRead = BytesProcessed(buffer.Offset, receiveBufferOffset); var bytesToWrite = Math.Min(_frameContentBytesLeft, buffer.BytesTransferred - bytesRead); _message.Body.Write(buffer.Buffer, receiveBufferOffset, bytesToWrite); _frameContentBytesLeft -= bytesToWrite; receiveBufferOffset += bytesToWrite; bytesLeftInReceiveBuffer -= bytesToWrite; if (_frameContentBytesLeft == 0) { _message.Body.Position = 0; TriggerMessageReceived(_message); Clear(); } } }
private bool ProcessContent(ISocketBuffer arg) { if (_bytesLeftForCurrentState == 0 || _bytesLeftInSocketBuffer == 0) { return(false); } var bytesToCopy = Math.Min(_bytesLeftForCurrentState, _bytesLeftInSocketBuffer); _contentStream.Write(arg.Buffer, _socketBufferOffset, bytesToCopy); _bytesLeftInSocketBuffer -= bytesToCopy; _bytesLeftForCurrentState -= bytesToCopy; _socketBufferOffset += bytesToCopy; if (_bytesLeftForCurrentState > 0) { return(false); } _bytesLeftForCurrentState = sizeof(short); _headerOffset = 0; _stateMethod = ReadHeaderLength; _contentStream.Position = 0; if (_contentName == "stream") { MessageReceived(_contentStream); } else if (_contentName == "byte[]") { MessageReceived(_contentStream); } else { var message = _serializer.Deserialize(_contentName, _contentStream); MessageReceived(message); } return(true); }
public void ProcessReadBytes(ISocketBuffer buffer) { var offset = buffer.Offset; var count = buffer.BytesTransferred; // start by reading header. if (!_isHeaderRead) { var headerBytesRead = Math.Min(_headerBytesLeft, count); Buffer.BlockCopy(buffer.Buffer, offset, _headerBuf, _headerOffset, headerBytesRead); _headerBytesLeft -= headerBytesRead; // have not received all bytes left. // can occur if we send a lot of messages so that the nagle algorithm merges // messages so that the header is in the end of the socket stream. if (_headerBytesLeft > 0) { return; } count -= headerBytesRead; offset += headerBytesRead; _bytesLeft = BitConverter.ToInt32(_headerBuf, 0); _isHeaderRead = true; } var bodyBytesToRead = Math.Min(_bytesLeft, count); _stream.Write(buffer.Buffer, offset, bodyBytesToRead); _bytesLeft -= bodyBytesToRead; if (_bytesLeft == 0) { _stream.Position = 0; var item = _serializer.Deserialize(new StreamReader(_stream), typeof(object)); MessageReceived(item); Clear(); //TODO: Recursive call to read any more messages } }
public void ProcessReadBytes(ISocketBuffer buffer) { var offset = buffer.Offset; var count = buffer.BytesTransferred; // start by reading header. if (!_isHeaderRead) { var headerBytesRead = Math.Min(_headerBytesLeft, count); Buffer.BlockCopy(buffer.Buffer, offset, _headerBuf, _headerOffset, headerBytesRead); _headerBytesLeft -= headerBytesRead; // have not received all bytes left. // can occur if we send a lot of messages so that the nagle algorithm merges // messages so that the header is in the end of the socket stream. if (_headerBytesLeft > 0) return; count -= headerBytesRead; offset += headerBytesRead; _bytesLeft = BitConverter.ToInt32(_headerBuf, 0); _isHeaderRead = true; } var bodyBytesToRead = Math.Min(_bytesLeft, count); _stream.Write(buffer.Buffer, offset, bodyBytesToRead); _bytesLeft -= bodyBytesToRead; if (_bytesLeft == 0) { _stream.Position = 0; var item = _serializer.Deserialize(new StreamReader(_stream), typeof(object)); MessageReceived(item); Clear(); //TODO: Recursive call to read any more messages } }
/// <summary> /// Buffer structure used for socket send operations. /// </summary> /// <param name="buffer"> /// Do note that there are not buffer attached to the structure, you have to assign one yourself using /// <see cref="ISocketBuffer.SetBuffer(int,int)" />. This choice was made /// to prevent unnecessary copy operations. /// </param> public void Send(ISocketBuffer buffer) { if (_bytesToSend > 0) { buffer.SetBuffer(_buffer, _offset, _bytesToSend, _bytesToSend); return; } if (_isHeaderSent) { var bytes = Math.Min(_totalAmountToSend, _buffer.Length); _frame.Body.Read(_buffer, 0, bytes); _bytesToSend = bytes; // include null char as message delimter if (bytes < _buffer.Length) { buffer.Buffer[_bytesToSend] = 0; bytes++; } buffer.SetBuffer(_buffer, 0, bytes, bytes); return; } if (_frame.Name == "NoOp") { _bytesToSend = 0; buffer.Buffer[0] = 10; buffer.SetBuffer(0, 1); return; } _writer.Write("{0}\n", _frame.Name); foreach (var header in _frame.Headers) { _writer.Write("{0}:{1}\n", header.Key, header.Value); } _writer.Write("\n"); _writer.Flush(); _isHeaderSent = true; if (_frame.Body == null || _frame.ContentLength == 0) { _stream.Write(new byte[] { 0 }, 0, 1); _bytesToSend = (int)_stream.Length; _totalAmountToSend = _bytesToSend; buffer.SetBuffer(_buffer, 0, (int)_stream.Length); return; } var bytesLeft = _buffer.Length - _stream.Length; var bytesToSend = Math.Min(_frame.ContentLength, (int)bytesLeft); var offset = (int)_stream.Position; _frame.Body.Read(_buffer, offset, bytesToSend); _bytesToSend = (int)_stream.Length + bytesToSend; _totalAmountToSend = (int)_stream.Length + _frame.ContentLength + 1; // everything is done in the first run // so add the message delimiter. if (_totalAmountToSend < buffer.Count) { _totalAmountToSend++; _bytesToSend++; _buffer[_bytesToSend] = 0; } buffer.SetBuffer(_buffer, 0, _totalAmountToSend); }
public bool ProcessFixedHeader(ISocketBuffer e) { if (!CopyBytes(e)) return false; _protocolVersion = _header[0]; _contentLength = BitConverter.ToInt32(_header, 1); _typeLength = _header[5]; _contentName = Encoding.ASCII.GetString(_header, 6, _typeLength); _stateMethod = ProcessContent; _bytesLeftForCurrentState = _contentLength; _headerOffset = 0; _contentStream.SetLength(0); _contentStream.Position = 0; return true; }
/// <summary> /// We've received bytes from the socket. Build a message out of them. /// </summary> /// <param name="buffer">Buffer</param> /// <remarks></remarks> public void ProcessReadBytes(ISocketBuffer buffer) { throw new NotImplementedException(); }
/// <summary> /// Buffer structure used for socket send operations. /// </summary> /// <param name="buffer">Do note that there are not buffer attached to the structure, you have to assign one yourself using <see cref="ISocketBuffer.SetBuffer"/>. This choice was made /// to prevent unnecessary copy operations.</param> public void Send(ISocketBuffer buffer) { buffer.SetBuffer(Buffer, Offset, Count); }
/// <summary> /// Buffer structure used for socket send operations. /// </summary> /// <param name="buffer"> /// Do note that there are not buffer attached to the structure, you have to assign one yourself using /// <see cref="ISocketBuffer.SetBuffer" />. This choice was made /// to prevent unnecessary copy operations. /// </param> /// <remarks> /// The <c>buffer</c> variable is typically a wrapper around <see cref="SocketAsyncEventArgs" />, but may be something /// else if required. /// </remarks> public void Send(ISocketBuffer buffer) { buffer.SetBuffer(_buffer, _offset, _bytesLeft); }
/// <summary> /// We've received bytes from the socket. Build a message out of them. /// </summary> /// <param name="buffer">Buffer</param> /// <remarks></remarks> public void ProcessReadBytes(ISocketBuffer buffer) { int receiveBufferOffset = buffer.Offset; int bytesLeftInReceiveBuffer = buffer.BytesTransferred; while (true) { if (bytesLeftInReceiveBuffer <= 0) { break; } if (!_isHeaderParsed) { var offsetBefore = receiveBufferOffset; receiveBufferOffset = _headerParser.Parse(buffer, receiveBufferOffset); if (!_isHeaderParsed) { return; } bytesLeftInReceiveBuffer -= receiveBufferOffset - offsetBefore; _frameContentBytesLeft = _frame.ContentLength; if (_frameContentBytesLeft == 0) { // the NULL message delimiter if (bytesLeftInReceiveBuffer == 1) { bytesLeftInReceiveBuffer = 0; } MessageReceived(_frame); _frame = null; _isHeaderParsed = false; continue; } _frame.Body = new MemoryStream(); } var bytesRead = BytesProcessed(buffer.Offset, receiveBufferOffset); var bytesToWrite = Math.Min(_frameContentBytesLeft, buffer.BytesTransferred - bytesRead); _frame.Body.Write(buffer.Buffer, receiveBufferOffset, bytesToWrite); _frameContentBytesLeft -= bytesToWrite; receiveBufferOffset += bytesToWrite; bytesLeftInReceiveBuffer -= bytesToWrite; bytesRead += bytesToWrite; if (_frameContentBytesLeft == 0) { // ignore NULL (message delimiter) //TODO: Maybe verify it? ;) var bytesRemaining = buffer.BytesTransferred - bytesRead; if (bytesRemaining == 1) { bytesLeftInReceiveBuffer--; receiveBufferOffset++; } _frame.Body.Position = 0; MessageReceived(_frame); Clear(); } } }
/// <summary> /// Buffer structure used for socket send operations. /// </summary> /// <param name="buffer"> /// Do note that there are not buffer attached to the structure, you have to assign one yourself using /// <see cref="ISocketBuffer.SetBuffer(int,int)" />. This choice was made /// to prevent unnecessary copy operations. /// </param> public void Send(ISocketBuffer buffer) { if (_message == null) { _httpMessageEncoder.Send(buffer); } else { // last send operation did not send all bytes enqueued in the buffer // so let's just continue until doing next message if (_bytesToSend > 0) { buffer.SetBuffer(_buffer, _offset, _bytesToSend); return; } var offset = (int)_message.Payload.Position; var length = (int)_message.Payload.Length; var frameLength = length - offset; var fin = WebSocketFin.Final; if (frameLength > WebSocketFrame.FragmentLength) { frameLength = WebSocketFrame.FragmentLength; fin = WebSocketFin.More; } var opcode = WebSocketOpcode.Continuation; if (offset == 0) // first frame { opcode = _message.Opcode; } var buff = new byte[frameLength]; _message.Payload.Read(buff, 0, buff.Length); var payload = new MemoryStream(buff); WebSocketFrame frame = new WebSocketFrame(fin, opcode, (_handshake is IHttpRequest) ? WebSocketMask.Mask : WebSocketMask.Unmask, payload); using (var stream = new MemoryStream()) { var header = (int)frame.Fin; header = (header << 1) + (int)frame.Rsv1; header = (header << 1) + (int)frame.Rsv2; header = (header << 1) + (int)frame.Rsv3; header = (header << 4) + (int)frame.Opcode; header = (header << 1) + (int)frame.Mask; header = (header << 7) + (int)frame.PayloadLength; stream.Write(WebSocketUtils.GetBigEndianBytes((ushort)header), 0, 2); if (frame.PayloadLength > 125) { stream.Write(frame.ExtPayloadLength, 0, frame.ExtPayloadLength.Length); } if (frame.Mask == WebSocketMask.Mask) { stream.Write(frame.MaskingKey, 0, frame.MaskingKey.Length); frame.Unmask(); } _totalAmountToSend += (int)stream.Length; if (frame.PayloadLength > 0) { frame.Payload.CopyTo(stream); } buffer.UserToken = _message; _buffer = stream.ToArray(); _bytesToSend = _buffer.Length; buffer.SetBuffer(_buffer, 0, _bytesToSend); } } }
/// <summary> /// Buffer structure used for socket send operations. /// </summary> /// <param name="buffer"> /// Do note that there are not buffer attached to the structure, you have to assign one yourself using /// <see cref="ISocketBuffer.SetBuffer(int,int)" />. This choice was made /// to prevent unnecessary copy operations. /// </param> public void Send(ISocketBuffer buffer) { if (_bytesToSend > 0) { buffer.SetBuffer(_buffer, _offset, _bytesToSend, _bytesToSend); return; } if (_isHeaderSent) { var bytes = Math.Min(_totalAmountToSend, _buffer.Length); _frame.Body.Read(_buffer, 0, bytes); _bytesToSend = bytes; // include null char as message delimter if (bytes < _buffer.Length) { buffer.Buffer[_bytesToSend] = 0; bytes++; } buffer.SetBuffer(_buffer, 0, bytes, bytes); return; } if (_frame.Name == "NoOp") { _bytesToSend = 0; buffer.Buffer[0] = 10; buffer.SetBuffer(0, 1); return; } _writer.Write("{0}\n", _frame.Name); foreach (var header in _frame.Headers) { _writer.Write("{0}:{1}\n", header.Key, header.Value); } _writer.Write("\n"); _writer.Flush(); _isHeaderSent = true; if (_frame.Body == null || _frame.ContentLength == 0) { _stream.Write(new byte[] {0}, 0, 1); _bytesToSend = (int) _stream.Length; _totalAmountToSend = _bytesToSend; buffer.SetBuffer(_buffer, 0, (int) _stream.Length); return; } var bytesLeft = _buffer.Length - _stream.Length; var bytesToSend = Math.Min(_frame.ContentLength, (int) bytesLeft); var offset = (int) _stream.Position; _frame.Body.Read(_buffer, offset, bytesToSend); _bytesToSend = (int) _stream.Length + bytesToSend; _totalAmountToSend = (int) _stream.Length + _frame.ContentLength + 1; // everything is done in the first run // so add the message delimiter. if (_totalAmountToSend < buffer.Count) { _totalAmountToSend++; _bytesToSend++; _buffer[_bytesToSend] = 0; } buffer.SetBuffer(_buffer, 0, _totalAmountToSend); }
/// <summary> /// We've received bytes from the socket. Build a message out of them. /// </summary> /// <param name="buffer">Buffer</param> /// <remarks></remarks> public void ProcessReadBytes(ISocketBuffer buffer) { }
/// <summary> /// We've received bytes from the socket. Build a message out of them. /// </summary> /// <param name="buffer">Buffer</param> public void ProcessReadBytes(ISocketBuffer buffer) { if (!_isWebSocket) { _httpMessageDecoder.ProcessReadBytes(buffer); } else { var receiveBufferOffset = buffer.Offset; var bytesLeftInReceiveBuffer = buffer.BytesTransferred; while (true) { if (bytesLeftInReceiveBuffer <= 0) { break; } if (_frame == null) { var first = buffer.Buffer[receiveBufferOffset + 0]; var second = buffer.Buffer[receiveBufferOffset + 1]; var fin = (first & 0x80) == 0x80 ? WebSocketFin.Final : WebSocketFin.More; var rsv1 = (first & 0x40) == 0x40 ? WebSocketRsv.On : WebSocketRsv.Off; var rsv2 = (first & 0x20) == 0x20 ? WebSocketRsv.On : WebSocketRsv.Off; var rsv3 = (first & 0x10) == 0x10 ? WebSocketRsv.On : WebSocketRsv.Off; var opcode = (WebSocketOpcode)(first & 0x0f); var mask = (second & 0x80) == 0x80 ? WebSocketMask.Mask : WebSocketMask.Unmask; var payloadLen = (byte)(second & 0x7f); receiveBufferOffset += 2; bytesLeftInReceiveBuffer -= 2; // TODO: // check if valid headers // control frame && payloadLen > 125 // control frame && more // not data && compressed var size = payloadLen < 126 ? 0 : payloadLen == 126 ? 2 : 8; var extPayloadLen = new byte[size]; for (var i = 0; i < size; i++) { extPayloadLen[i] = buffer.Buffer[receiveBufferOffset + i]; } receiveBufferOffset += size; bytesLeftInReceiveBuffer -= size; var maskingKey = new byte[0]; if (mask == WebSocketMask.Mask) { maskingKey = new byte[] { buffer.Buffer[receiveBufferOffset + 0], buffer.Buffer[receiveBufferOffset + 1], buffer.Buffer[receiveBufferOffset + 2], buffer.Buffer[receiveBufferOffset + 3], }; receiveBufferOffset += 4; bytesLeftInReceiveBuffer -= 4; } ulong len = payloadLen < 126 ? payloadLen : payloadLen == 126 ? WebSocketUtils.ToBigEndianUInt16(extPayloadLen) : WebSocketUtils.ToBigEndianUInt64(extPayloadLen); _frameContentBytesLeft = (int)len; _frame = new WebSocketFrame(fin, rsv1, rsv2, rsv3, opcode, mask, maskingKey, payloadLen, extPayloadLen, new MemoryStream(_frameContentBytesLeft)); if (_frame.Fin == WebSocketFin.More || _frame.Opcode == WebSocketOpcode.Continuation) { _frames.Add(_frame); } } if (_frameContentBytesLeft > 0) { var bytesRead = BytesProcessed(buffer.Offset, receiveBufferOffset); var bytesToWrite = Math.Min(_frameContentBytesLeft, buffer.BytesTransferred - bytesRead); _frame.Payload.Write(buffer.Buffer, receiveBufferOffset, bytesToWrite); _frameContentBytesLeft -= bytesToWrite; receiveBufferOffset += bytesToWrite; bytesLeftInReceiveBuffer -= bytesToWrite; } if (_frameContentBytesLeft == 0) { _frame.Payload.Position = 0; if (_frame.Fin == WebSocketFin.Final) { if (_frame.Opcode == WebSocketOpcode.Continuation) { TriggerMessageReceived(_frames); _frames = new List <WebSocketFrame>(); } else { TriggerMessageReceived(new[] { _frame }); } } _frame = null; } } } }
/// <summary> /// Buffer structure used for socket send operations. /// </summary> /// <param name="buffer"> /// Do note that there are not buffer attached to the structure, you have to assign one yourself using /// <see cref="ISocketBuffer.SetBuffer(int,int)" />. This choice was made /// to prevent unnecessary copy operations. /// </param> /// <remarks> /// The <c>buffer</c> variable is typically a wrapper around <see cref="SocketAsyncEventArgs" />, but may be something /// else if required. /// </remarks> public void Send(ISocketBuffer buffer) { buffer.SetBuffer(_buffer, _offset, _bytesLeft); }
/// <summary> /// We've received bytes from the socket. Build a message out of them. /// </summary> /// <param name="buffer"></param> public void ProcessReadBytes(ISocketBuffer buffer) { // buffer offset received var offsetInSocketBuffer = buffer.Offset; // Number of Bytes received _bytesReceived = buffer.BytesTransferred; while (true) { if (_bytesReceived <= 0) { break; } Buffer.BlockCopy(buffer.Buffer, offsetInSocketBuffer, _buffer, _offsetInOurBuffer, buffer.BytesTransferred); string textReceived = _encoding.GetString(_buffer); textReceived = textReceived.TrimStart(LINE_FEED_CHAR).Replace("\0", string.Empty); if (!textReceived.Contains(MESSAGE_END_STRING)) { _offsetInOurBuffer += _bytesReceived; return; } int contentLength = 0; string headerLine = textReceived.Substring(0, textReceived.IndexOf(MESSAGE_END_STRING, StringComparison.Ordinal)); var headers = ReadHeaderLines(headerLine); if (headers != null && headers.Count > 0) { if (headers.ContainsKey("Content-Length")) { contentLength = int.Parse(headers["Content-Length"]); } } int len; if (contentLength <= 0) { // Message does not have content length only headers. var decodedMessage = new EslDecodedMessage(headerLine, string.Empty, textReceived); MessageReceived(decodedMessage); Clear(); // Let us check whether there is another message in the buffer sent textReceived = textReceived.Substring(textReceived.IndexOf(MESSAGE_END_STRING, StringComparison.Ordinal) + MESSAGE_END_STRING.Length); if (string.IsNullOrEmpty(textReceived) || textReceived.Equals(MESSAGE_END_STRING) || textReceived.Equals(EOL)) { continue; } // Length of extra bytes len = _encoding.GetByteCount(textReceived); _encoding.GetBytes(textReceived, 0, textReceived.Length, _buffer, 0); _offsetInOurBuffer += len; } else { // Message does have body as well as header. string bodyLine = textReceived.Substring(textReceived.IndexOf(MESSAGE_END_STRING, StringComparison.Ordinal) + MESSAGE_END_STRING.Length); if (string.IsNullOrEmpty(bodyLine)) { len = _encoding.GetByteCount(textReceived); // We need to read more bytes for the body _offsetInOurBuffer += len; return; } // body has been read. However there are more to read to make it complete if (bodyLine.Length < contentLength) { // get the count of the received bytes len = _encoding.GetByteCount(textReceived); // The body is not yet complete we need to read more _offsetInOurBuffer += len; return; } // body has been fully read if (contentLength == bodyLine.Length) { MessageReceived(new EslDecodedMessage(headerLine, bodyLine, textReceived)); Clear(); return; } // There is another message in the buffer if (bodyLine.Length > contentLength) { string bodyLine2 = bodyLine.Substring(0, contentLength); MessageReceived(new EslDecodedMessage(headerLine, bodyLine2, headerLine + bodyLine2)); Clear(); textReceived = bodyLine.Remove(bodyLine.IndexOf(bodyLine2, StringComparison.Ordinal), bodyLine2.Length); if (string.IsNullOrEmpty(textReceived) || textReceived.Equals(MESSAGE_END_STRING) || textReceived.Equals(EOL)) { return; } // Length of extra bytes len = _encoding.GetByteCount(textReceived); _encoding.GetBytes(textReceived, 0, textReceived.Length, _buffer, 0); _offsetInOurBuffer += len; } } } }
public void Send(ISocketBuffer buffer) { // Continue from where the last send operation stopped. buffer.SetBuffer(_memoryStream.GetBuffer(), _offset, _bytesLeft); }
private bool ProcessContent(ISocketBuffer arg) { if (_bytesLeftForCurrentState == 0 || _bytesLeftInSocketBuffer == 0) return false; var bytesToCopy = Math.Min(_bytesLeftForCurrentState, _bytesLeftInSocketBuffer); _contentStream.Write(arg.Buffer, _socketBufferOffset, bytesToCopy); _bytesLeftInSocketBuffer -= bytesToCopy; _bytesLeftForCurrentState -= bytesToCopy; _socketBufferOffset += bytesToCopy; if (_bytesLeftForCurrentState > 0) { return false; } _bytesLeftForCurrentState = sizeof(short); _headerOffset = 0; _stateMethod = ReadHeaderLength; _contentStream.Position = 0; if (_contentName == "stream") MessageReceived(_contentStream); else if (_contentName == "byte[]") { MessageReceived(_contentStream); } else { var message = _serializer.Deserialize(_contentName, _contentStream); MessageReceived(message); } return true; }
public void ProcessReadBytes(ISocketBuffer buffer) { _bytesLeftInSocketBuffer = buffer.BytesTransferred; _socketBufferOffset = buffer.Offset; while (_stateMethod(buffer)) { } }
/// <summary> /// </summary> /// <param name="channel"></param> /// <param name="buffer"></param> /// <param name="completed"></param> /// <returns></returns> public int Process(ITcpChannel channel, ISocketBuffer buffer, out bool completed) { throw new NotSupportedException(); }
private bool CopyBytes(ISocketBuffer e) { if (_bytesLeftInSocketBuffer == 0) return false; if (_bytesLeftForCurrentState > 0) { var toCopy = Math.Min(_bytesLeftForCurrentState, _bytesLeftInSocketBuffer); Buffer.BlockCopy(e.Buffer, _socketBufferOffset, _header, _headerOffset, toCopy); _headerOffset += toCopy; _bytesLeftForCurrentState -= toCopy; _bytesLeftInSocketBuffer -= toCopy; _socketBufferOffset += toCopy; } return _bytesLeftForCurrentState == 0; }
/// <summary> /// We've received bytes from the socket. Build a message out of them. /// </summary> /// <param name="buffer">Buffer</param> public void ProcessReadBytes(ISocketBuffer buffer) { if (!_isWebSocket) { _httpMessageDecoder.ProcessReadBytes(buffer); } else { var receiveBufferOffset = buffer.Offset; var bytesLeftInReceiveBuffer = buffer.BytesTransferred; while (true) { if (bytesLeftInReceiveBuffer <= 0) break; if (_frame == null) { var first = buffer.Buffer[receiveBufferOffset + 0]; var second = buffer.Buffer[receiveBufferOffset + 1]; var fin = (first & 0x80) == 0x80 ? WebSocketFin.Final : WebSocketFin.More; var rsv1 = (first & 0x40) == 0x40 ? WebSocketRsv.On : WebSocketRsv.Off; var rsv2 = (first & 0x20) == 0x20 ? WebSocketRsv.On : WebSocketRsv.Off; var rsv3 = (first & 0x10) == 0x10 ? WebSocketRsv.On : WebSocketRsv.Off; var opcode = (WebSocketOpcode)(first & 0x0f); var mask = (second & 0x80) == 0x80 ? WebSocketMask.Mask : WebSocketMask.Unmask; var payloadLen = (byte)(second & 0x7f); receiveBufferOffset += 2; bytesLeftInReceiveBuffer -= 2; // TODO: // check if valid headers // control frame && payloadLen > 125 // control frame && more // not data && compressed var size = payloadLen < 126 ? 0 : payloadLen == 126 ? 2 : 8; var extPayloadLen = new byte[size]; for (var i = 0; i < size; i++) { extPayloadLen[i] = buffer.Buffer[receiveBufferOffset + i]; } receiveBufferOffset += size; bytesLeftInReceiveBuffer -= size; var maskingKey = new byte[0]; if (mask == WebSocketMask.Mask) { maskingKey = new byte[] { buffer.Buffer[receiveBufferOffset + 0], buffer.Buffer[receiveBufferOffset + 1], buffer.Buffer[receiveBufferOffset + 2], buffer.Buffer[receiveBufferOffset + 3], }; receiveBufferOffset += 4; bytesLeftInReceiveBuffer -= 4; } ulong len = payloadLen < 126 ? payloadLen : payloadLen == 126 ? WebSocketUtils.ToBigEndianUInt16(extPayloadLen) : WebSocketUtils.ToBigEndianUInt64(extPayloadLen); _frameContentBytesLeft = (int)len; _frame = new WebSocketFrame(fin, rsv1, rsv2, rsv3, opcode, mask, maskingKey, payloadLen, extPayloadLen, new MemoryStream(_frameContentBytesLeft)); if (_frame.Fin == WebSocketFin.More || _frame.Opcode == WebSocketOpcode.Continuation) { _frames.Add(_frame); } } if (_frameContentBytesLeft > 0) { var bytesRead = BytesProcessed(buffer.Offset, receiveBufferOffset); var bytesToWrite = Math.Min(_frameContentBytesLeft, buffer.BytesTransferred - bytesRead); _frame.Payload.Write(buffer.Buffer, receiveBufferOffset, bytesToWrite); _frameContentBytesLeft -= bytesToWrite; receiveBufferOffset += bytesToWrite; bytesLeftInReceiveBuffer -= bytesToWrite; } if (_frameContentBytesLeft == 0) { _frame.Payload.Position = 0; if (_frame.Fin == WebSocketFin.Final) { if (_frame.Opcode == WebSocketOpcode.Continuation) { TriggerMessageReceived(_frames); _frames = new List<WebSocketFrame>(); } else { TriggerMessageReceived(new[] { _frame }); } } _frame = null; } } } }
/// <summary> /// We've received bytes from the socket. Build a message out of them. /// </summary> /// <param name="buffer"></param> public void ProcessReadBytes(ISocketBuffer buffer) { // buffer offset received var offsetInSocketBuffer = buffer.Offset; // Number of Bytes received _bytesReceived = buffer.BytesTransferred; while (true) { if (_bytesReceived <= 0) break; Buffer.BlockCopy(buffer.Buffer, offsetInSocketBuffer, _buffer, _offsetInOurBuffer, buffer.BytesTransferred); string textReceived = _encoding.GetString(_buffer); textReceived = textReceived.TrimStart(LINE_FEED_CHAR).Replace("\0", string.Empty); if (!textReceived.Contains(MESSAGE_END_STRING)) { _offsetInOurBuffer += _bytesReceived; return; } int contentLength = 0; string headerLine = textReceived.Substring(0, textReceived.IndexOf(MESSAGE_END_STRING, StringComparison.Ordinal)); var headers = ReadHeaderLines(headerLine); if (headers != null && headers.Count > 0) if (headers.ContainsKey("Content-Length")) contentLength = int.Parse(headers["Content-Length"]); int len; if (contentLength <= 0) { // Message does not have content length only headers. var decodedMessage = new EslDecodedMessage(headerLine, string.Empty, textReceived); MessageReceived(decodedMessage); Clear(); // Let us check whether there is another message in the buffer sent textReceived = textReceived.Substring(textReceived.IndexOf(MESSAGE_END_STRING, StringComparison.Ordinal) + MESSAGE_END_STRING.Length); if (string.IsNullOrEmpty(textReceived) || textReceived.Equals(MESSAGE_END_STRING) || textReceived.Equals(EOL)) continue; // Length of extra bytes len = _encoding.GetByteCount(textReceived); _encoding.GetBytes(textReceived, 0, textReceived.Length, _buffer, 0); _offsetInOurBuffer += len; } else { // Message does have body as well as header. string bodyLine = textReceived.Substring(textReceived.IndexOf(MESSAGE_END_STRING, StringComparison.Ordinal) + MESSAGE_END_STRING.Length); if (string.IsNullOrEmpty(bodyLine)) { len = _encoding.GetByteCount(textReceived); // We need to read more bytes for the body _offsetInOurBuffer += len; return; } // body has been read. However there are more to read to make it complete if (bodyLine.Length < contentLength) { // get the count of the received bytes len = _encoding.GetByteCount(textReceived); // The body is not yet complete we need to read more _offsetInOurBuffer += len; return; } // body has been fully read if (contentLength == bodyLine.Length) { MessageReceived(new EslDecodedMessage(headerLine, bodyLine, textReceived)); Clear(); return; } // There is another message in the buffer if (bodyLine.Length > contentLength) { string bodyLine2 = bodyLine.Substring(0, contentLength); MessageReceived(new EslDecodedMessage(headerLine, bodyLine2, headerLine+ bodyLine2)); Clear(); textReceived = bodyLine.Remove(bodyLine.IndexOf(bodyLine2, StringComparison.Ordinal), bodyLine2.Length); if (string.IsNullOrEmpty(textReceived) || textReceived.Equals(MESSAGE_END_STRING) || textReceived.Equals(EOL)) return; // Length of extra bytes len = _encoding.GetByteCount(textReceived); _encoding.GetBytes(textReceived, 0, textReceived.Length, _buffer, 0); _offsetInOurBuffer += len; } } } }
/// <summary> /// 回收 /// </summary> /// <param name="item"></param> public void Recycle(ISocketBuffer item) { this.groups.Enqueue(item.Group); }