Daniel
Daniel

Reputation: 1418

Multiple clients async connection, sync send/receive

I'm a newbie to C#, OOP,Networking and TCP/IP sockets...

I have a misunderstanding regarding the usage of Async TCP/IP socket communication. I'm trying to create a server which waits for several clients, and each time a client connects it displays something like "user 192.168.1.105:2421 joined"

I thought that when you use BeginAccept() a new thread will be created...whenever a new user connects, and it will take care of the communication with that specific client. However, the following code blocks...and doesn't display the message for the second client.

What should I change so that for each connected client I have a separate thread which takes care of the execution?

class Server
{
    Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    //constructor 
    public Server()
    {
        listener.Bind(new IPEndPoint(IPAddress.Parse("192.168.1.100"), 9050));
        listener.Listen(10);
        listener.BeginAccept(new AsyncCallback(OnConnectRequest), listener);
        Console.Write("Server Running...\r\n");
    }

    public void OnConnectRequest(IAsyncResult ar)
    {
        Socket listener = (Socket)ar.AsyncState;
        NewConnection(listener.EndAccept(ar));
        listener.BeginAccept(new AsyncCallback(OnConnectRequest), listener);
    }

    //send a string message over a TCP socket 
    public void sendMSG(string msg,Socket socket)
    {
     //some code which sends data according to my protocol
    }

    public byte[] receiveMSG(ref Socket socket)
    {
     //some code which receives data according to my protocol
    }


    //function called whenever a NEW CLIENT is connected
    public void NewConnection(Socket sockClient)
    {
        Console.WriteLine("user {0} has joined",sockClient.RemoteEndPoint);
        byte[] msg = new byte[20];
        sockClient.Receive(msg);
    }

Upvotes: 1

Views: 3383

Answers (1)

Martin Baulig
Martin Baulig

Reputation: 3010

BeginAccept() accepts one single request, so your async callback will only be called once for the first request. This is the standard C# async pattern.

If you want to accept multiple requests, you need to call BeginAccept() again when you're done handling your request.

See also Asynchronous server socket multiple clients.

Edit:

You should call BeginAccept() between EndAccept() and NewConnection() if you want to permit concurrent requests:

public void OnConnectRequest(IAsyncResult ar)
{
    Socket listener = (Socket)ar.AsyncState;
    Socket accepted = listener.EndAccept(ar);
    listener.BeginAccept(new AsyncCallback(OnConnectRequest), listener);
    NewConnection(accepted);
}

Upvotes: 2

Related Questions