2016-10-17 6 views
0

私はサーバーソケットを初めて使用しています。単純なアプリケーションを作成しようとすると、この問題が発生しました。私はサーバーアプリケーションに接続するだけでなく、再接続することができます。しかし、2回目を切断すると、エラーが発生します。ここに私のコードは、私は誰かが私がなぜ理解するのを助けることを願っています。上記のコード内のコメントに見られるようにクライアントとサーバーアプリケーションの接続を切断してから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でSystem.Net.Sockets.Socket.Listen(のInt32バックログ)System.Net.Sockets.TcpListener.Startで
(のInt32バックログ)

ですで... \ Program.csを.TcpListener.Start Server.Program.waitForConnectionで()
():行55

+0

http://stackoverflow.com/questions/27182180/how-to-reconnect-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)); 
    } 
} 

ところで:クライアントが近ければclientSocket.Receive(prefBuffer)は0を返します、あなたは、このケースを処理する必要があります。

+0

ありがとうございました。 – paul

関連する問題