Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accept TCP Client Async

I've been making a server. I am using TcpListener.AcceptTcpClientAsync() in an async method, but I have no idea how to actually make it work. My code right now is:

private static async void StartServer()
{
    Console.WriteLine("S: Server started on port {0}", WebVars.ServerPort);
    var listener = new TcpListener(WebVars.LocalIp, WebVars.ServerPort);
    listener.Start();
    var client = await listener.AcceptTcpClientAsync();
}

How do I process the client? Do I just continue coding and it will automagically make new threads of the same method or do I need to do some magic method that will do it for me?

Edit: current code:

private static Task HandleClientAsync(TcpClient client)
{
    var stream = client.GetStream();
    // do stuff
}
/// <summary>
/// Method to be used on seperate thread.
/// </summary>
private static async void RunServerAsync()
{
    while (true)
    {
        Console.WriteLine("S: Server started on port {0}", WebVars.ServerPort);
        var listener = new TcpListener(WebVars.LocalIp, WebVars.ServerPort);
        listener.Start();
        var client = await listener.AcceptTcpClientAsync();
        await HandleClientAsync(client);
    }
}
like image 489
Ilan Avatar asked Mar 05 '14 06:03

Ilan


1 Answers

// all credit should go to c# 7.0 in a nutshell (Joseph Albahari & Ben Albahari)

    async void RunServerAsync()
    {
        var listner = new TcpListener(IPAddress.Any, 9999);
        listner.Start();
        try
        {
            while (true)
                await Accept(await listner.AcceptTcpClientAsync());
        }
        finally { listner.Stop(); }
    }


    const int packet_length = 2;  // user defined packet length

    async Task Accept(TcpClient client)
    {
        await Task.Yield();
        try
        {
            using(client)
            using(NetworkStream n = client.GetStream())
            {
                byte[] data = new byte[packet_length];
                int bytesRead = 0;
                int chunkSize = 1;

                while (bytesRead < data.Length && chunkSize > 0)
                    bytesRead += chunkSize = 
                        await n.ReadAsync(data, bytesRead, data.Length - bytesRead);

                // get data
                string str = Encoding.Default.GetString(data);
                Console.WriteLine("[server] received : {0}", str);

                // To do
                // ...

                // send the result to client
                string send_str = "server_send_test";
                byte[] send_data = Encoding.ASCII.GetBytes(send_str);
                await n.WriteAsync(send_data, 0, send_data.Length);

            }
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
like image 177
sailfish009 Avatar answered Sep 22 '22 17:09

sailfish009