static void OnReceive(Udp udp, IDatagramReadCompletion completion) { if (completion.Error != null) { completion.Dispose(); Console.WriteLine($"{nameof(EchoServer)} receive error {completion.Error}"); udp.ReceiveStop(); udp.CloseHandle(OnClose); return; } ReadableBuffer data = completion.Data; string message = data.ReadString(Encoding.UTF8); data.Dispose(); IPEndPoint remoteEndPoint = completion.RemoteEndPoint; if (string.IsNullOrEmpty(message) || remoteEndPoint == null) { return; } WritableBuffer buffer = WritableBuffer.From(Encoding.UTF8.GetBytes(message)); udp.QueueSend(buffer, remoteEndPoint, OnSendCompleted); }
static void OnAccept(StreamHandle stream, ReadableBuffer data) { if (data.Count == 0) { return; } string message = data.ReadString(data.Count, Encoding.UTF8); data.Dispose(); Console.WriteLine($"Echo client received : {message}"); Console.WriteLine("Message received, sending QS to server"); byte[] array = Encoding.UTF8.GetBytes("QS"); WritableBuffer buffer = WritableBuffer.From(array); stream.QueueWriteStream(buffer, OnWriteCompleted); }
private void OnAccept(Tcp client, ReadableBuffer data) { if (data.Count == 0) { log($"server OnAccept: data count is 0"); return; } ////log($"server read {data.Count}"); Interlocked.Increment(ref this.receiveCount); // Echo back var buffer = new byte[data.Count]; data.ReadBytes(buffer, buffer.Length); data.Dispose(); var writableBuffer = WritableBuffer.From(buffer); client.QueueWriteStream( writableBuffer, (streamHandle, exception) => { writableBuffer.Dispose(); if (exception != null) { log($"server write error: {exception.Message}"); streamHandle.CloseHandle(h => h.Dispose()); } else { client.OnRead( this.OnAccept, (_h, _e) => { log($"read error {_e.Message}"); }); } }); ////log($"server wrote {buffer.Length}"); }
private void OnAccept(StreamHandle stream, ReadableBuffer data) { if (data.Count == 0) { log($"client OnAccept: data count is 0"); return; } ////log($"client accept {data.Count}"); // Echo back var buffer = new byte[data.Count]; data.ReadBytes(buffer, buffer.Length); data.Dispose(); var writableBuffer = WritableBuffer.From(buffer); stream.QueueWriteStream( writableBuffer, (handle, exception) => { writableBuffer.Dispose(); if (exception != null) { log($"client write error: {exception.Message}"); handle.CloseHandle(h => h.Dispose()); } else { stream.OnRead( this.OnAccept, (_h, _e) => { log($"read error {_e.Message}"); }); } }); ////log($"client wrote {buffer.Length}"); }
static void OnAccept(StreamHandle stream, ReadableBuffer data) { string message = data.Count > 0 ? data.ReadString(data.Count, Encoding.UTF8) : null; data.Dispose(); if (string.IsNullOrEmpty(message)) { return; } Console.WriteLine($"Server received : {message}"); // // Scan for the letter Q which signals that we should quit the server. // If we get QS it means close the stream. // if (message.StartsWith("Q")) { Console.WriteLine("Server closing stream."); stream.Dispose(); if (!message.EndsWith("QS")) { return; } Console.WriteLine("Server shutting down."); eventLoop.ScheduleStop(); } else { Console.WriteLine("Server sending echo back."); byte[] array = Encoding.UTF8.GetBytes($"ECHO [{message}]"); WritableBuffer buffer = WritableBuffer.From(array); stream.QueueWriteStream(buffer, OnWriteCompleted); } }
private void CompletePreviousSending() { _sendingBuffer.Dispose(); _previousSendsComplete.Release(); }
internal static async Task <HttpRequest> ParseHttpRequest(IReadableChannel _input) { ReadableBuffer Method = default(ReadableBuffer), Path = default(ReadableBuffer), HttpVersion = default(ReadableBuffer); Dictionary <string, ReadableBuffer> Headers = new Dictionary <string, ReadableBuffer>(); try { ParsingState _state = ParsingState.StartLine; bool needMoreData = true; while (needMoreData) { var buffer = await _input.ReadAsync(); var consumed = buffer.Start; needMoreData = true; try { if (buffer.IsEmpty && _input.Reading.IsCompleted) { throw new EndOfStreamException(); } if (_state == ParsingState.StartLine) { // Find \n ReadCursor delim; ReadableBuffer startLine; if (!buffer.TrySliceTo((byte)'\r', (byte)'\n', out startLine, out delim)) { continue; } // Move the buffer to the rest buffer = buffer.Slice(delim).Slice(2); ReadableBuffer method; if (!startLine.TrySliceTo((byte)' ', out method, out delim)) { throw new Exception(); } Method = method.Preserve(); // Skip ' ' startLine = startLine.Slice(delim).Slice(1); ReadableBuffer path; if (!startLine.TrySliceTo((byte)' ', out path, out delim)) { throw new Exception(); } Path = path.Preserve(); // Skip ' ' startLine = startLine.Slice(delim).Slice(1); var httpVersion = startLine; if (httpVersion.IsEmpty) { throw new Exception(); } HttpVersion = httpVersion.Preserve(); _state = ParsingState.Headers; consumed = buffer.Start; } // Parse headers // key: value\r\n while (!buffer.IsEmpty) { var ch = buffer.Peek(); if (ch == -1) { break; } if (ch == '\r') { // Check for final CRLF. buffer = buffer.Slice(1); ch = buffer.Peek(); buffer = buffer.Slice(1); if (ch == -1) { break; } else if (ch == '\n') { consumed = buffer.Start; needMoreData = false; break; } // Headers don't end in CRLF line. throw new Exception(); } var headerName = default(ReadableBuffer); var headerValue = default(ReadableBuffer); // End of the header // \n ReadCursor delim; ReadableBuffer headerPair; if (!buffer.TrySliceTo((byte)'\n', out headerPair, out delim)) { break; } buffer = buffer.Slice(delim).Slice(1); // : if (!headerPair.TrySliceTo((byte)':', out headerName, out delim)) { throw new Exception(); } headerName = headerName.TrimStart(); headerPair = headerPair.Slice(delim).Slice(1); // \r if (!headerPair.TrySliceTo((byte)'\r', out headerValue, out delim)) { // Bad request throw new Exception(); } headerValue = headerValue.TrimStart(); Headers[ToHeaderKey(ref headerName)] = headerValue.Preserve(); // Move the consumed consumed = buffer.Start; } } finally { _input.Advance(consumed); } } var result = new HttpRequest(Method, Path, HttpVersion, Headers); Method = Path = HttpVersion = default(ReadableBuffer); Headers = null; return(result); } finally { Method.Dispose(); Path.Dispose(); HttpVersion.Dispose(); if (Headers != null) { foreach (var pair in Headers) { pair.Value.Dispose(); } } } }
private static async Task <HttpRequest> ParseHttpRequest(IReadableChannel _input) { ReadableBuffer Method = default(ReadableBuffer), Path = default(ReadableBuffer), HttpVersion = default(ReadableBuffer); Dictionary <string, ReadableBuffer> Headers = new Dictionary <string, ReadableBuffer>(); try { ParsingState _state = ParsingState.StartLine; bool needMoreData = true; while (needMoreData) { var buffer = await _input; var consumed = buffer.Start; needMoreData = true; try { if (buffer.IsEmpty && _input.Completion.IsCompleted) { throw new EndOfStreamException(); } if (_state == ParsingState.StartLine) { // Find \n var delim = buffer.IndexOf(ref _vectorLFs); if (delim.IsEnd) { continue; } // Grab the entire start line var startLine = buffer.Slice(0, delim); // Move the buffer to the rest buffer = buffer.Slice(delim).Slice(1); delim = startLine.IndexOf(ref _vectorSpaces); if (delim.IsEnd) { throw new Exception(); } var method = startLine.Slice(0, delim); Method = method.Preserve(); // Skip ' ' startLine = startLine.Slice(delim).Slice(1); delim = startLine.IndexOf(ref _vectorSpaces); if (delim.IsEnd) { throw new Exception(); } var path = startLine.Slice(0, delim); Path = path.Preserve(); // Skip ' ' startLine = startLine.Slice(delim).Slice(1); delim = startLine.IndexOf(ref _vectorCRs); if (delim.IsEnd) { throw new Exception(); } var httpVersion = startLine.Slice(0, delim); HttpVersion = httpVersion.Preserve(); _state = ParsingState.Headers; consumed = startLine.End; } // Parse headers // key: value\r\n while (!buffer.IsEmpty) { var ch = buffer.Peek(); if (ch == -1) { break; } if (ch == '\r') { // Check for final CRLF. buffer = buffer.Slice(1); ch = buffer.Peek(); buffer = buffer.Slice(1); if (ch == -1) { break; } else if (ch == '\n') { consumed = buffer.Start; needMoreData = false; break; } // Headers don't end in CRLF line. throw new Exception(); } var headerName = default(ReadableBuffer); var headerValue = default(ReadableBuffer); // End of the header // \n var delim = buffer.IndexOf(ref _vectorLFs); if (delim.IsEnd) { break; } var headerPair = buffer.Slice(0, delim); buffer = buffer.Slice(delim).Slice(1); // : delim = headerPair.IndexOf(ref _vectorColons); if (delim.IsEnd) { throw new Exception(); } headerName = headerPair.Slice(0, delim).TrimStart(); headerPair = headerPair.Slice(delim).Slice(1); // \r delim = headerPair.IndexOf(ref _vectorCRs); if (delim.IsEnd) { // Bad request throw new Exception(); } headerValue = headerPair.Slice(0, delim).TrimStart(); Headers[ToHeaderKey(ref headerName)] = headerValue.Preserve(); // Move the consumed consumed = buffer.Start; } } finally { buffer.Consumed(consumed); } } var result = new HttpRequest(Method, Path, HttpVersion, Headers); Method = Path = HttpVersion = default(ReadableBuffer); Headers = null; return(result); } finally { Method.Dispose(); Path.Dispose(); HttpVersion.Dispose(); if (Headers != null) { foreach (var pair in Headers) { pair.Value.Dispose(); } } } }