user2536272
user2536272

Reputation: 69

beginAccept() asynchronous server issue in C#

I'm struggling with some piece of simple code. However, I can't get it done. I have this server, which must accept connections from multiple clients (asynchronously, obviously). So, I have:

IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 8082);

TcpListener tcpListener = new TcpListener(IPAddress.Any, 8082);

server = tcpListener.Server;
server.Bind(ipEndPoint);
server.Listen(4);

server.BeginAccept(new AsyncCallback(beginConnection), server);

And,

static void beginConnection(IAsyncResult iar)
{
    Console.WriteLine("Client connected");
    Socket s = (Socket)iar.AsyncState;
    server = s.EndAccept(iar);

    server.Listen(4);
    server.BeginAccept(beginConnection, s);
}

Then, when I try to connect myself, the first client works OK. It just sends a message to this server, and the server sends it back to the client. The server functions as an echo. But when I try to connect another clients it doesn't work. I have also put the Console.WriteLine("Client connected"), but the server doesn't write anything. How can I fix this problem?

I think I'm not passing the right parameter to the first BeginAccept method. Instead of server socket, I should be passing the tcpListener.

Then I would have:

static void beginConnection(IAsyncResult iar)
{
    Console.WriteLine("Client connected");
    TcpListener tcpListener = (TcpListener)iar.AsyncState;
    Socket s = tcpListener.Server.EndAccept(iar);

    tcpListener.Server = s; // But I would have this error

    server.Listen(2);
    server.BeginAccept(beginConnection, s);
}

But I would have the error that I marked it up. In the first version nothing is modified, so I think this it's the issue in the first version of the code.

Upvotes: 0

Views: 4167

Answers (1)

AgentFire
AgentFire

Reputation: 9780

First, you do not need the Server property of the TcpListener. You should simply call Start(), even without Bind.

Second, EndAccept() is also should be called at TcpListener and return a TcpClient instance which you must use for sending and receiving data.

A simple example of what I just said might be presented as:

{
    TcpListener listener = new TcpListener(IPAddress.Any, 8082);
    listener.Start();

    AcceptClient();
}

void AcceptClient()
{ 
    listener.BeginAccept(ClientConnected, null);
}

void ClientConnected(IAsyncResult ar)
{
    TcpClient client = listener.EndAccept();
    AcceptClient();

    // Now you can send or receive data using the client variable.
}

Upvotes: 2

Related Questions