2

So I tried the following program to make an async server, when its sync its easy and i can only speak with the server with 1 connection because the second one isn't allowed. I make a class Server.cs with my server implementation. For the clinet I use Microsoft Telnet.

Program.cs:

static void Main(string[] args)
    {
        Server myServer = new Server();
        myServer.StartListening();
        Console.ReadKey();
    }

Server.cs

class Server
{
    //Delegates
    delegate void socketConnection();
    socketConnection myConnection;

    //Needed for connections
    public IPEndPoint serverIPEP { get; set; }
    public Socket serverSocket { get; set; }
    public int numberOfConnections { get; set; }
    public List<Socket> activeConnections;

    //Constructors
    public Server()
    {
        serverIPEP = new IPEndPoint(IPAddress.Any, 9080);
        serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        numberOfConnections = 10;
        activeConnections = new List<Socket>(numberOfConnections);
    }

    public Server(IPEndPoint serverIPEP)
    {
        this.serverIPEP = serverIPEP;
        serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        numberOfConnections = 10;
        activeConnections = new List<Socket>(numberOfConnections);
    }

    public Server(Socket serverSocket)
    {
        serverIPEP = new IPEndPoint(IPAddress.Any, 9080);
        this.serverSocket = serverSocket;
        numberOfConnections = 10;
        activeConnections = new List<Socket>(numberOfConnections);
    }

    public Server(IPEndPoint serverIPEP, Socket serverSocket, int numberOfConnections)
    {
        this.serverIPEP = serverIPEP;
        this.serverSocket = serverSocket;
        this.numberOfConnections = numberOfConnections;
        activeConnections = new List<Socket>(numberOfConnections);
    }

    public void StartListening()
    {
        serverSocket.Bind(serverIPEP);
        serverSocket.Listen(numberOfConnections);

        Console.WriteLine("Waiting for connections...");

        //Here I made a loop with the callback :) I don't think its the cleverest implementation
        myConnection = new socketConnection(GetConnections);
        IAsyncResult connectionResult = myConnection.BeginInvoke(callBack, this);

        //connectionResult.AsyncWaitHandle.WaitOne();
    }

    private void GetConnections()
    {
        Socket clientSocket = serverSocket.Accept();
        activeConnections.Add(clientSocket);
    }

    private void callBack(IAsyncResult itfAR)
    {
        Console.WriteLine("Current thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId);
        myConnection.BeginInvoke(callBack, this);
    }

The problem is that when I connect with 2 clients it tells me that they are on the same thread, and I want them to be on separated threads. It tells me:

Waiting for connections...
Current thread: 7
Current thread: 7

Shouldn't there be another number like thread 7 and then thread 9? Or it happens like this because I connect to the server from the same computer?

Thanatos
  • 1,176
  • 8
  • 18

2 Answers2

1

Shouldn't there be another number like thread 7 and then thread 9? Or it happens like this because I connect to the server from the same computer?

Delegate.BeginInvoke grabs a thread from the thread pool. The reason you are seeing the same thread Id is because that thread is idle. If the thread was busy then BeginInvoke will grab some other thread. For example:

 private void callBack(IAsyncResult itfAR)
    {
        Console.WriteLine("Current thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId);
        myConnection.BeginInvoke(callBack, this);
        Thread.Sleep(100000);
    }
Raj Ranjhan
  • 3,869
  • 2
  • 19
  • 29
0

There are a few things that are not quite right in your code. You are never ending the accept on the original socket, so I think, since your clients are both from the same address, you are just sending a constant stream of data to the original listen invocation (I could be wrong on that particular detail, as I haven't really traced through your code very thoroughly).

In your callback, you want to end the first connection after getting whatever data sent it, then spawn a new one. Also, you want to encapsulate your StartListening() method in a loop, and set an event handler when you are through with the connection.

There is a pretty good example of an async socket listener on the MSDN site. I use a modified version to fit my purposes, but the principle is solid.

Using an Asynchronous Server Socket

Sean H
  • 736
  • 6
  • 9