コード例 #1
0
        /// <summary>
        ///     Starts the TCP server loop listening for client connections on the Server Socket, then
        ///     communicating with the client on that client's TCP Connection Socket.
        /// </summary>
        public override void Start()
        {
            ListenSocket = Transport.GetSocket(IPAddress.Any.AddressFamily);
            ListenSocket.Bind(IpEndPoint);
            ListenSocket.Listen(10);
            Console.WriteLine("TCP Server Socket awaiting connection from client");
            Console.WriteLine("Press ESC to stop this server");

            var shutdownToken = new CancellationTokenSource();
            var socketTasks = new ConcurrentBag<Task>();

            var serverSocketTask = Task.Run(() =>
            {
                //loop to listen for TCP connections while token isn't
                while (!shutdownToken.IsCancellationRequested)
                {
                    try
                    {
                        Console.WriteLine("\r\nTCP Server Socket waiting at {0}", ListenSocket.LocalEndPoint);

                        var newClientSocket = ListenSocket.Accept();

                        Connections++;
                        Console.WriteLine("\r\nConnections: {0}", Connections);
                        var client = new TcpClientConnection(newClientSocket, Transport.BufferSize);
                        var clientTask = Task.Factory.StartNew(() =>
                        {
                            client.Execute();
                            Task toRemove;
                            socketTasks.TryTake(out toRemove); //remove from concurrent bag
                            Connections--;
                            Console.WriteLine("\r\nConnections: {0}", Connections);
                        }, shutdownToken.Token);
                        socketTasks.Add(clientTask);
                    }
                    catch (OperationCanceledException)
                    {
                        //time to shutdown
                    }
                }
            }, shutdownToken.Token); //cancel this task when token is flagged
            socketTasks.Add(serverSocketTask);

            //wait for connections
            while (Console.ReadKey(true).Key != ConsoleKey.Escape)
            {
            }

            //no more waiting... shutdown
            Console.WriteLine("Stopping... closing open TCP connections");
            shutdownToken.CancelAfter(1000); //give tasks 1000ms to finish - then throw them if necessary
            Task.WaitAll(socketTasks.ToArray(), 1000); //wait up to 5 seconds for all tasks to end, then give up

            Stop();
        }