See the problem in the picture. The Server starts a new Task for accepting the clients and then handles it in the function Handle(client), this all works fine, but it every time it repeats this one message "Client connecting...", but it shouldn't. Nothing else of the Task is called but this message. And the bool Pending() is false, so it shouldn't start another Task.
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();
}
}
}
}
Client connecting shouldn't repeat every time, everything else works
Emrah Süngü's comments seem accurate and correct
TcpClient client = _tcpListener.AcceptTcpClient(); // accept first
Console.WriteLine("Client connecting...");
// then start processing in your task
Task.Run(() => this.Handle(client));
It makes perfect sense when you think about it, you are in a while loop, and you are starting several tasks before the code to except the client actually runs.
Disclaimer : This is totally untested and i am not responsible for and harm you cause to others or your self with this code :)