Повторение сообщения, но не следует повторять это сообщение в Задаче - PullRequest
0 голосов
/ 26 декабря 2018

problem См. Проблему на картинке.Сервер запускает новую задачу для принятия клиентов, а затем обрабатывает ее в функции Handle (client), все это прекрасно работает, но каждый раз повторяет это одно сообщение «Клиент подключается ...», но это не должно.Ничто другое из Задания не вызывается, кроме этого сообщения.И bool Pending () имеет значение false, поэтому он не должен запускать другую задачу.

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace WebServer
{
    class WebServer
    {
        public static WebServer Server { get; private set; }

        private TcpListener _tcpListener = null;
        public CancellationTokenSource TokenSource { get; private set; }
        public CancellationToken Token { get; private set; }

        public int i = 0;

        static void Main(string[] args)
        {
            WebServer.Server = new WebServer();
        }

        WebServer()
        {
            IPAddress ipAddress;

            try
            {
                ipAddress = IPAddress.Parse("127.0.0.1");
            } catch(Exception e)
            {
                Console.WriteLine("Error while parsing ip address: " + e.Message);
                return;
            }

            _tcpListener = new TcpListener(ipAddress, 8080);
            _tcpListener.Start();

            TokenSource = new CancellationTokenSource();
            Token = TokenSource.Token;

            //Execute server
            Task.Run(() => Run());

            Console.ReadKey();
            TokenSource.Cancel();

            WaitHandle handle = Token.WaitHandle;
            handle.WaitOne();
        }

        private void Run()
        {
            Console.WriteLine("Server is runnning");
            while(!Token.IsCancellationRequested)
            {
                if(_tcpListener.Pending())
                {
                    Console.WriteLine("Pending: " + _tcpListener.Pending());
                    Task.Run(() => {
                        Console.WriteLine("Client connecting...");
                        TcpClient client = _tcpListener.AcceptTcpClient();

                        this.Handle(client);
                        return;
                    });
                }
            }
        }

        private void Handle(TcpClient client)
        {
            NetworkStream stream = client.GetStream();

            Console.WriteLine("Handling....");

            while(client.Connected)
            {
                if(stream.DataAvailable)
                {
                    Console.WriteLine("Start Reading...");
                    byte[] buffer = new byte[1024];
                    stream.Read(buffer, 0, 1024);
                    Console.WriteLine("Read: " + Encoding.ASCII.GetString(buffer));
                }

                client.Close();
            }
        }
    }
}

Подключение клиента не должно повторяться каждый раз, все остальное работает

1 Ответ

0 голосов
/ 26 декабря 2018

Комментарии Эмры Сюнгу кажутся точными и правильными

TcpClient client = _tcpListener.AcceptTcpClient(); // accept first
Console.WriteLine("Client connecting...");

// then start processing in your task
Task.Run(() => this.Handle(client));

Это имеет смысл, когда вы думаете об этом, вы находитесь в цикле while и запускаете несколько задач перед тем, как код, за исключением клиента на самом делеработает.

Отказ от ответственности : Это полностью не проверено, и я не несу ответственности и не причиняю вам вред другим или себе с этим кодом:)

...