コード例 #1
0
        static IEnumerator <object> SendTask(SocketDataAdapter adapter)
        {
            var output = new AsyncTextWriter(adapter, Encoding.ASCII);

            output.AutoFlush = true;
            Writer           = output;
            string nextMessageText = String.Format("ChatBot{0:00000}", Process.GetCurrentProcess().Id);

            Console.Title = nextMessageText;
            int i = 0;

            yield return(new Sleep(new Random(Process.GetCurrentProcess().Id).NextDouble()));

            while (true)
            {
                var f = output.WriteLine(nextMessageText);
                yield return(f);

                if (f.Failed)
                {
                    Disconnected = true;
                    throw new DisconnectedException();
                }

                i += 1;

                if ((i % 1000) == 0)
                {
                    Console.WriteLine("Sent: {0}", i);
                }

                nextMessageText = String.Format("Message {0}", i);
                yield return(new Sleep(SendRate));
            }
        }
コード例 #2
0
        static IEnumerator <object> ReceiveTask(SocketDataAdapter adapter)
        {
            var    input   = new AsyncTextReader(adapter, Encoding.ASCII);
            int    i       = 0;
            string message = null;

            Reader = input;
            while (true)
            {
                var f = input.ReadLine();
                yield return(f);

                if (!f.GetResult(out message))
                {
                    throw new DisconnectedException();
                }

                if (message == null)
                {
                    throw new DisconnectedException();
                }
                else
                {
                    i += 1;
                }

                if ((i % 1000) == 0)
                {
                    Console.WriteLine("Recieved: {0}", i);
                }
            }
        }
コード例 #3
0
        private IEnumerator <object> KeepAliveTask(ListenerContext context, Socket socket)
        {
            EndPoint localEp = socket.LocalEndPoint, remoteEp = socket.RemoteEndPoint;
            var      evtArgs = new ConnectionEventArgs(localEp, remoteEp);

            if (SocketOpened != null)
            {
                SocketOpened(this, evtArgs);
            }

            try {
                using (var adapter = new SocketDataAdapter(socket, true)) {
                    while (!adapter.IsDisposed && adapter.Socket.Connected)
                    {
                        var fTask = Scheduler.Start(RequestTask(context, adapter));
                        yield return(fTask);

                        if (fTask.Failed)
                        {
                            adapter.Dispose();
                            yield break;
                        }
                    }
                }
            } finally {
                if (SocketClosed != null)
                {
                    SocketClosed(this, evtArgs);
                }
            }
        }
コード例 #4
0
        private IEnumerator <object> KeepAliveTask(ListenerContext context, IncomingConnection incomingConnection)
        {
            var      socket = incomingConnection.Socket;
            EndPoint localEp = socket.LocalEndPoint, remoteEp = socket.RemoteEndPoint;
            var      evtArgs = new ConnectionEventArgs(localEp, remoteEp);

            var keepAliveStarted = DateTime.UtcNow;

            if (SocketOpened != null)
            {
                SocketOpened(this, evtArgs);
            }

            int requestCount = 0;

            try {
                using (var adapter = new SocketDataAdapter(socket, true)) {
                    while (!adapter.IsDisposed && adapter.Socket.Connected)
                    {
                        var fTask = Scheduler.Start(RequestTask(context, adapter));
                        yield return(fTask);

                        requestCount += 1;

                        if (fTask.Failed)
                        {
                            adapter.Dispose();
                            yield break;
                        }
                    }
                }
            } finally {
                var keepAliveEnded = DateTime.UtcNow;

                if (SocketClosed != null)
                {
                    SocketClosed(this, evtArgs);
                }

                if (Trace != null)
                {
                    Trace(
                        String.Format(
                            "KA_START {0:0000.0}ms  KA_LENGTH {1:00000.0}ms  {2} REQ(S)",
                            (keepAliveStarted - incomingConnection.AcceptedWhenUTC).TotalMilliseconds,
                            (keepAliveEnded - keepAliveStarted).TotalMilliseconds,
                            requestCount
                            )
                        );
                }
            }
        }
コード例 #5
0
        public void Dispose()
        {
            if (Data != null)
            {
                Data.Dispose();
                Data = null;
            }

            if (_SendFuture != null)
            {
                _SendFuture.Dispose();
                _SendFuture = null;
            }
        }
コード例 #6
0
        static IEnumerator <object> PeerTask(TcpClient client, Peer peer)
        {
            var adapter = new SocketDataAdapter(client.Client, true);
            var input   = new AsyncTextReader(adapter, Encoding.ASCII);
            var output  = new AsyncTextWriter(adapter, Encoding.ASCII);

            adapter.ThrowOnDisconnect     = false;
            adapter.ThrowOnFullSendBuffer = false;
            output.AutoFlush = true;

            peer.Input  = input;
            peer.Output = output;

            yield return(output.WriteLine("Welcome! Please enter your name."));

            string name = null;

            yield return(input.ReadLine().Bind(() => name));

            if (name == null)
            {
                PeerDisconnected(peer);
                yield break;
            }

            peer.Name = name;

            PeerConnected(peer);

            yield return(output.Write(VT100.EraseScreen));

            string nextLine = null;

            while (peer.Connected)
            {
                var f = input.ReadLine();
                yield return(f);

                if (!f.GetResult(out nextLine) || nextLine == null)
                {
                    PeerDisconnected(peer);
                    yield break;
                }

                if (nextLine.Length > 0)
                {
                    DispatchNewMessage(peer, nextLine);
                }
            }
        }
コード例 #7
0
        internal TelnetClient(TelnetServer server, TcpClient client)
        {
            Server = server;
            client.Client.NoDelay  = true;
            client.Client.Blocking = false;
            Data = new SocketDataAdapter(client.Client, true);
            Data.ThrowOnDisconnect     = false;
            Data.ThrowOnFullSendBuffer = false;
            Encoding encoding = Encoding.ASCII;

            Input            = new AsyncTextReader(Data, encoding);
            Output           = new AsyncTextWriter(Data, encoding);
            Output.AutoFlush = true;
            _SendFuture      = server._Scheduler.Start(SendMessagesTask(), TaskExecutionPolicy.RunWhileFutureLives);
        }
コード例 #8
0
            internal Request(
                HttpServer server, SocketDataAdapter adapter, bool shouldKeepAlive,
                RequestLine line, HeaderCollection headers, RequestBody body
                )
            {
                WeakServer = new WeakReference(server);

                LocalEndPoint  = adapter.Socket.LocalEndPoint;
                RemoteEndPoint = adapter.Socket.RemoteEndPoint;

                Line     = line;
                Headers  = headers;
                Body     = body;
                Response = new Response(this, adapter, shouldKeepAlive);

                server.OnRequestCreated(this);
            }
コード例 #9
0
        static void Main(string[] args)
        {
            if ((args.Length < 1) || !float.TryParse(args[0], out SendRate))
            {
                SendRate = 1.0f;
            }

            Thread.CurrentThread.Name = "MainThread";
            ThreadPool.SetMinThreads(1, 1);

            try {
                Console.WriteLine("Connecting to server...");
                var f = Network.ConnectTo("localhost", 1234);
                f.GetCompletionEvent().Wait();
                Console.WriteLine("Connected.");
                TcpClient client = f.Result as TcpClient;
                client.Client.Blocking = false;
                client.Client.NoDelay  = true;
                SocketDataAdapter adapter = new SocketDataAdapter(client.Client);
                adapter.ThrowOnDisconnect     = false;
                adapter.ThrowOnFullSendBuffer = false;

                Scheduler.Start(ReceiveTask(adapter), TaskExecutionPolicy.RunAsBackgroundTask);
                Scheduler.Start(SendTask(adapter), TaskExecutionPolicy.RunAsBackgroundTask);

                while (!Disconnected)
                {
                    Scheduler.Step();
                    Scheduler.WaitForWorkItems();
                }
                Console.WriteLine("Disconnected.");
            } catch (Exception ex) {
                if (ex is TaskException && ex.InnerException is DisconnectedException)
                {
                }
                else
                {
                    Console.WriteLine(ex.ToString());
                }
            }
        }
コード例 #10
0
ファイル: Request.cs プロジェクト: sq/Libraries
        private IEnumerator <object> RequestTask(ListenerContext context, SocketDataAdapter adapter)
        {
            var  startedWhen = DateTime.UtcNow;
            bool successful  = false;

            try {
                const int    headerBufferSize   = 1024 * 32;
                const int    bodyBufferSize     = 1024 * 128;
                const double requestLineTimeout = 5;

                // RFC2616:
                // Words of *TEXT MAY contain characters from character sets other than ISO-8859-1 [22]
                //  only when encoded according to the rules of RFC 2047 [14].
                Encoding headerEncoding;
                try {
                    headerEncoding = Encoding.GetEncoding("ISO-8859-1");
                } catch {
                    headerEncoding = Encoding.ASCII;
                }

                Request          request;
                RequestBody      body;
                HeaderCollection headers;
                long             bodyBytesRead      = 0;
                long?            expectedBodyLength = null;

                var    reader = new AsyncTextReader(adapter, headerEncoding, headerBufferSize, false);
                string requestLineText;

                while (true)
                {
                    var fRequestLine      = reader.ReadLine();
                    var fRequestOrTimeout = Scheduler.Start(new WaitWithTimeout(fRequestLine, requestLineTimeout));

                    yield return(fRequestOrTimeout);

                    if (fRequestOrTimeout.Failed)
                    {
                        if (!(fRequestOrTimeout.Error is TimeoutException))
                        {
                            OnRequestError(fRequestOrTimeout.Error);
                        }

                        yield break;
                    }

                    if (fRequestLine.Failed)
                    {
                        if (!(fRequestLine.Error is SocketDisconnectedException))
                        {
                            OnRequestError(fRequestLine.Error);
                        }

                        yield break;
                    }

                    requestLineText = fRequestLine.Result;

                    // RFC2616:
                    // In the interest of robustness, servers SHOULD ignore any empty line(s) received where a
                    //  Request-Line is expected. In other words, if the server is reading the protocol stream
                    //   at the beginning of a message and receives a CRLF first, it should ignore the CRLF.
                    if ((requestLineText != null) && (requestLineText.Trim().Length == 0))
                    {
                        continue;
                    }

                    break;
                }

                var requestLineParsed = DateTime.UtcNow;

                headers = new HeaderCollection();
                while (true)
                {
                    var fHeaderLine = reader.ReadLine();
                    yield return(fHeaderLine);

                    if (String.IsNullOrWhiteSpace(fHeaderLine.Result))
                    {
                        break;
                    }

                    headers.Add(new Header(fHeaderLine.Result));
                }

                var headersParsed = DateTime.UtcNow;

                var expectHeader    = (headers.GetValue("Expect") ?? "").ToLowerInvariant();
                var expectsContinue = expectHeader.Contains("100-continue");

                string hostName;
                if (headers.Contains("Host"))
                {
                    hostName = String.Format("http://{0}", headers["Host"].Value);
                }
                else
                {
                    var lep = (IPEndPoint)adapter.Socket.LocalEndPoint;
                    hostName = String.Format("http://{0}:{1}", lep.Address, lep.Port);
                }

                var requestLine = new RequestLine(hostName, requestLineText);

                var remainingBytes = reader.DisposeAndGetRemainingBytes();
                bodyBytesRead += remainingBytes.Count;

                var connectionHeader = (headers.GetValue("Connection") ?? "").ToLowerInvariant();
                var shouldKeepAlive  =
                    ((requestLine.Version == "1.1") || connectionHeader.Contains("keep-alive")) &&
                    !connectionHeader.Contains("close");

                if (headers.Contains("Content-Length"))
                {
                    expectedBodyLength = long.Parse(headers["Content-Length"].Value);
                }

                body = new RequestBody(remainingBytes, expectedBodyLength);

                if (expectsContinue)
                {
                    yield return(adapter.Write(Continue100, 0, Continue100.Length));
                }

                request = new Request(
                    this, adapter, shouldKeepAlive,
                    requestLine, headers, body
                    );

                IncomingRequests.Enqueue(request);

                var      requestEnqueued = DateTime.UtcNow;
                DateTime?requestBodyRead = null;

                // FIXME: I think it's technically accepted to send a body without a content-length, but
                //  it seems to be impossible to make that work right.
                if (expectedBodyLength.HasValue)
                {
                    using (var bodyBuffer = BufferPool <byte> .Allocate(bodyBufferSize))
                        while (bodyBytesRead < expectedBodyLength.Value)
                        {
                            long bytesToRead = Math.Min(expectedBodyLength.Value - bodyBytesRead, bodyBufferSize);

                            if (bytesToRead <= 0)
                            {
                                break;
                            }

                            var fBytesRead = adapter.Read(bodyBuffer.Data, 0, (int)bytesToRead);
                            yield return(fBytesRead);

                            if (fBytesRead.Failed)
                            {
                                if (fBytesRead.Error is SocketDisconnectedException)
                                {
                                    break;
                                }

                                body.Failed(fBytesRead.Error);
                                OnRequestError(fBytesRead.Error);
                                yield break;
                            }

                            var bytesRead = fBytesRead.Result;

                            bodyBytesRead += bytesRead;
                            body.Append(bodyBuffer.Data, 0, bytesRead);
                        }

                    requestBodyRead = DateTime.UtcNow;
                }

                body.Finish();
                successful = true;

                request.Timing = new Request.TimingData {
                    Line    = (requestLineParsed - startedWhen),
                    Headers = (headersParsed - requestLineParsed),
                    Queue   = (requestEnqueued - headersParsed),
                    Body    = (requestBodyRead - requestEnqueued)
                };
            } finally {
                if (!successful)
                {
                    adapter.Dispose();
                }
            }
        }