简体   繁体   English

断开连接,然后将客户端重新连接到服务器应用程序C#

[英]Disconnect then reconnect client to server application C#

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) 在System.Net.Sockets.Socket.Listen(Int32积压)
at System.Net.Sockets.TcpListener.Start(Int32 backlog) 在System.Net.Sockets.TcpListener.Start(Int32积压)
at System.Net.Sockets.TcpListener.Start() 在System.Net.Sockets.TcpListener.Start()
at Server.Program.waitForConnection() in ...\\Program.cs:line 55 在... \\ Program.cs:line 55中的Server.Program.waitForConnection()中

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标志引起的。 running is static variable and it is shared between the thread. running是静态变量,在线程之间共享。 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. 每次连接丢失时,您将running设置为false,但是该线程将阻塞,直到建立新连接,然后running将再次变为true。 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. 您需要中断循环,但需要特别注意,因为启动新线程和关闭线程是并发的,也许首先关闭线程并且新线程已开始完成,这将关闭应用程序,因为有时会关闭应用程序t有效线程正在运行。

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. 如果您只想处理同一运行线程中的连接,我认为该错误是由两次调用startRunThread()引起的。 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. 顺便说一句:如果客户端关闭, clientSocket.Receive(prefBuffer)将返回零,您需要处理这种情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM