Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set up TcpListener to always listen and accept multiple connections?

This is my Server App:

public static void Main() {     try     {         IPAddress ipAddress = IPAddress.Parse("127.0.0.1");          Console.WriteLine("Starting TCP listener...");          TcpListener listener = new TcpListener(ipAddress, 500);          listener.Start();          while (true)         {             Console.WriteLine("Server is listening on " + listener.LocalEndpoint);              Console.WriteLine("Waiting for a connection...");              Socket client = listener.AcceptSocket();              Console.WriteLine("Connection accepted.");              Console.WriteLine("Reading data...");              byte[] data = new byte[100];             int size = client.Receive(data);             Console.WriteLine("Recieved data: ");             for (int i = 0; i < size; i++)                 Console.Write(Convert.ToChar(data[i]));              Console.WriteLine();              client.Close();         }          listener.Stop();     }     catch (Exception e)     {         Console.WriteLine("Error: " + e.StackTrace);         Console.ReadLine();     } } 

As you can see , it always listens while working , but I would like to specify that I want the app be able to listen and to have multiple connections support in the same time.

How could I modify this to constantly listen while also accepting the multiple connections?

like image 798
keeehlan Avatar asked Oct 15 '13 17:10

keeehlan


People also ask

What is a TCP listener?

The TcpListener type is used to monitor a TCP port for incoming requests and then create either a Socket or a TcpClient that manages the connection to the client. The Start method enables listening, and the Stop method disables listening on the port.

What is TCP listener in C#?

The TcpListener class provides simple methods that listen for and accept incoming connection requests in blocking synchronous mode. You can use either a TcpClient or a Socket to connect with a TcpListener. Create a TcpListener using an IPEndPoint, a Local IP address and port number, or just a port number.

What is TCP client?

The TcpClient class provides simple methods for connecting, sending, and receiving stream data over a network in synchronous blocking mode. In order for TcpClient to connect and exchange data, a TcpListener or Socket created with the TCP ProtocolType must be listening for incoming connection requests.


2 Answers

  1. The socket on which you want to listen for incoming connections is commonly referred to as the listening socket.

  2. When the listening socket acknowledges an incoming connection, a socket that commonly referred to as a child socket is created that effectively represents the remote endpoint.

  3. In order to handle multiple client connections simultaneously, you will need to spawn a new thread for each child socket on which the server will receive and handle data.
    Doing so will allow for the listening socket to accept and handle multiple connections as the thread on which you are listening will no longer be blocking or waiting while you wait for the incoming data.

while (true) {    Socket client = listener.AcceptSocket();    Console.WriteLine("Connection accepted.");         var childSocketThread = new Thread(() =>    {        byte[] data = new byte[100];        int size = client.Receive(data);        Console.WriteLine("Recieved data: ");                for (int i = 0; i < size; i++)        {            Console.Write(Convert.ToChar(data[i]));        }         Console.WriteLine();             client.Close();     });      childSocketThread.Start(); } 
like image 174
User 12345678 Avatar answered Oct 04 '22 10:10

User 12345678


I had a similar problem today, and solved it like this:

while (listen) // <--- boolean flag to exit loop {    if (listener.Pending())    {       Thread tmp_thread = new Thread(new ThreadStart(() =>       {          string msg = null;           TcpClient clt = listener.AcceptTcpClient();           using (NetworkStream ns = clt.GetStream())          using (StreamReader sr = new StreamReader(ns))          {             msg = sr.ReadToEnd();          }           Console.WriteLine("Received new message (" + msg.Length + " bytes):\n" + msg);       }       tmp_thread.Start();    }    else    {        Thread.Sleep(100); //<--- timeout    } } 

My loop did not get stuck on waiting for a connection and it did accept multiple connections.


EDIT: The following code snippet is the async-equivalent using Tasks instead of Threads. Please note that the code contains C#-8 constructs.

private static TcpListener listener = .....; private static bool listen = true; // <--- boolean flag to exit loop   private static async Task HandleClient(TcpClient clt) {     using NetworkStream ns = clt.GetStream();     using StreamReader sr = new StreamReader(ns);     string msg = await sr.ReadToEndAsync();      Console.WriteLine($"Received new message ({msg.Length} bytes):\n{msg}"); }  public static async void Main() {     while (listen)         if (listener.Pending())             await HandleClient(await listener.AcceptTcpClientAsync());         else             await Task.Delay(100); //<--- timeout } 
like image 24
unknown6656 Avatar answered Oct 04 '22 09:10

unknown6656