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

时间:2016-10-17 19:08:49

标签: c#

我是服务器套接字的新手,在尝试创建一个简单的应用程序时遇到了这个问题。我可以很好地连接到服务器应用程序,然后重新连接。但是当我第二次断开连接时出现错误。这是我的代码,希望有人能帮我理解原因。

    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();
    }

如上面代码中的注释所示,即使我重新初始化它,也会收到错误消息,说我无法访问已处置的对象? 这是堆栈跟踪

  

at System.Net.Sockets.Socket.Listen(Int32 backlog)
      在System.Net.Sockets.TcpListener.Start(Int32 backlog)
      在System.Net.Sockets.TcpListener.Start()
      在... \ Program.cs中的Server.Program.waitForConnection():第55行

1 个答案:

答案 0 :(得分:0)

如果你想开始新的开始新线程来处理新连接,我认为错误是由running的标志引起的。 running是静态变量,它在线程之间共享。每次连接丢失时,您设置running为false,但该线程将阻塞直到新连接,并且running将再次变为true。旧线程不会关闭。你需要打破循环,但是你需要注意它,因为启动新线程和关闭线程是并发的,可能是第一个关闭线程并且新线程开始完成,这将关闭应用程序,因为在某个时候,有没有' 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();
}

如果您只想处理同一个运行线程中的连接,我认为该错误是由调用startRunThread()两次引起的。你可以像这样修改。

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)将返回零,您需要处理这种情况。