2016-10-17 117 views
0

我是新來的服務器套接字任何東西,當試圖創建一個簡單的應用程序,我遇到了這個問題。我可以很好地連接到服務器應用程序,並重新連接。但是當我第二次斷開連接時出現錯誤。這裏是我的代碼,我希望有人能幫助我理解爲什麼。斷開然後重新連接客戶端到服務器應用程序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(); 
    } 

正如上面的代碼出現在註釋得到一個錯誤,即使我重新初始化它,我不能訪問一個釋放的對象? 這裏是堆棧跟蹤

在System.Net.Sockets.Socket.Listen(的Int32積壓)
在System.Net.Sockets.TcpListener.Start(的Int32積壓)
在的System.Net.Sockets .TcpListener.Start()在
在Server.Program.waitForConnection()... \的Program.cs:行55

+0

http://stackoverflow.com/questions/27182180/how-to-re-connect-to-a-socket-gracefully – Larry

回答

0

如果你想開始新的開始新的線程來處理新的連接,我覺得該錯誤是由running的標誌引起的。 running是靜態變量,它在線程之間共享。每次連接丟失時,您將running設置爲false,但該線程將阻塞,直到新連接和running將再次變爲true。舊的線程不會關閉。你需要打破循環,但你需要小心,因爲開始新線程和關閉線程是併發的,也許第一個關閉線程和新線程開始完成,這將關閉應用程序,因爲在某個時候,有效的線程運行。

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)將返回零,如果客戶是接近的,你需要處理這種情況。

+0

非常感謝你,我永遠不會想到這一點。 – paul

相關問題