0

I'm new to server socket anything and when attempting to create a simple application I ran into this problem. I can connect to the server application just fine as well as reconnect again. But when i disconnect the second time I get an error. Here is my code, I hope someone can help me understand why.

    private static TcpListener clientListener;
    private static Socket clientSocket;

    private static bool running = false;
    private static Thread runThread;

    static void Main(string[] args){

        writeMsg(">> Server started");
        waitForConnection();
    }

    private static void writeMsg(String msg){
        Console.WriteLine(msg);
    }

    private static void run(){
        while (running){
            try{
                byte[] prefBuffer = new byte[100];
                int bufferSize = clientSocket.Receive(prefBuffer);
                writeMsg(">> Data recieved from client");
                for (int i = 0; i < bufferSize; i++){
                    Console.Write(Convert.ToChar(prefBuffer[i]));
                }
            }
            catch{
                writeMsg("Connection Lost");
                running = false;
                clientListener.Stop();
                clientSocket.Close();
                waitForConnection();
            }
        }
        runThread.Abort();
    }

    private static void waitForConnection(){
        //This is the where the error is created and it says...
        //Cannot access disposed object.
        clientListener = new TcpListener(IPAddress.Parse("111.111.111.111"), 7414);
        clientListener.Start();
        writeMsg(">> Listening for connections...");
        try{
            clientSocket = clientListener.AcceptSocket();
            writeMsg(">> Connection established");
            running = true;
            startRunThread();
        }
        catch (Exception e){
            writeMsg(String.Format(">> Connection failed\n Error: {0}", e.Message));
        }
    }

    private static void startRunThread(){
        runThread = new Thread(new ThreadStart(run));
        runThread.Start();
    }

As seen in the comments in the above code a get an error saying I cannot access a disposed object even though I reinitialized it? Here is the stack trace

at System.Net.Sockets.Socket.Listen(Int32 backlog)
at System.Net.Sockets.TcpListener.Start(Int32 backlog)
at System.Net.Sockets.TcpListener.Start()
at Server.Program.waitForConnection() in ...\Program.cs:line 55

Manfred Radlwimmer
  • 13,257
  • 13
  • 53
  • 62
paul
  • 96
  • 9

1 Answers1

0

If you want to start new start new thread to handle the new connections, I think the error is caused by the flag of running. running is static variable and it is shared between the thread. Each time the connection lost, you set the running is false, but that thread will block until the new connection, and running will become true again. The old thread will not close. You need to break the loop, but you need to take careful about it, because start new thread and close thread is concurrence, maybe first close thread and the new thread is start finished, that will close the application because in sometime, there hasn't valid thread running.

private static void run(){
    while (running){
        try{
            byte[] prefBuffer = new byte[100];
            int bufferSize = clientSocket.Receive(prefBuffer);
            writeMsg(">> Data recieved from client");
            for (int i = 0; i < bufferSize; i++){
                Console.Write(Convert.ToChar(prefBuffer[i]));
            }
        }
        catch{
            writeMsg("Connection Lost");
            running = false;
            clientListener.Stop();
            clientSocket.Close();
            waitForConnection();
            break;
        }
    }
    runThread.Abort();
}

If you only want to handle the connections in the same run thread, I think the error is caused by the call startRunThread() twice. You can modify like this.

static void Main(string[] args)
{

    writeMsg(">> Server started");
    waitForConnection(true);
}

private static void run()
{
    while (running)
    {
        try
        {
            byte[] prefBuffer = new byte[100];
            int bufferSize = clientSocket.Receive(prefBuffer);
            if (bufferSize == 0)
            {
                throw new ApplicationException();
            }
            writeMsg(">> Data recieved from client");
            for (int i = 0; i < bufferSize; i++)
            {
                Console.Write(Convert.ToChar(prefBuffer[i]));
            }
        }
        catch
        {
            writeMsg("Connection Lost");
            running = false;
            clientSocket.Close();
            clientListener.Stop();
            waitForConnection(false);
        }
    }
    runThread.Abort();
}

private static void waitForConnection(bool newThread)
{
    //This is the where the error is created and it says...
    //Cannot access disposed object.
    clientListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 9091);
    clientListener.Start();
    writeMsg(">> Listening for connections...");
    try
    {
        clientSocket = clientListener.AcceptSocket();
        writeMsg(">> Connection established");
        running = true;
        if (newThread)
        {
            startRunThread();
        }
    }
    catch (Exception e)
    {
        writeMsg(String.Format(">> Connection failed\n Error: {0}", e.Message));
    }
}

BTW: clientSocket.Receive(prefBuffer) will return zero if the client is close, you need to handle this case.

zzczzc004
  • 131
  • 5