2009-04-27 46 views
0

所以我想在C#中爲我的服務器創建一個客戶端,它接受消息作爲命令,以便我可以遠程控制客戶端。我遇到問題後,我的masterServer.Connect採取FOREVER加載,幾乎每次我關閉我的應用程序,我不得不等待10秒,它完全停止。我已經嘗試了一切來阻止這個......沒有運氣。所以我已經放棄了,現在要解決另一個問題,我使用了一個masterServer = new TcpClient(),它似乎在CreateConnection()線程內工作得很好。但是,當線程完成,我什麼地方調用SendClientInfo()的路線,並導致此運行時錯誤:C#如何防止TcpClient對象在使用new關鍵字創建的不同線程中處置?

無法訪問已釋放的對象,System.Net.Sockets.TcpClient

所以我盡了最大的努力想辦法從保存對象之前將其丟棄或任何東西,但我無法找到如何去做。所以這裏是我的問題:

  1. 如何防止處置mainServer = new TcpClient(),以便我可以在我的SendClientInfo()上使用它?
  2. 任何人都可以重寫我的CreateConnection()方法,所以我可以看到如何做到這一點正確嗎?我重寫了這個東西一千次,仍然看起來非常麻煩,而masterServer.connect()需要FOREVER才能做,如果它還沒有連接到服務器。
  3. 您可以在此處看到的任何其他更改或修復。我一直在進出這個小時和幾小時,試圖通過閱讀一百篇教程來教自己如何使用套接字。任何你告訴我我做錯了的事情我會一直記住下次正確的做。

讓我知道你是否需要任何信息...我真的很感激它。

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Net; 
using System.Net.Sockets; 
using System.Threading; 
using System.IO; 

namespace RemoteClient 
{ 
    public partial class Form1 : Form 
    { 
     private int MyPort = 56789; 
     private IPAddress myIp = IPAddress.Parse("210.232.115.79"); 
     private IPAddress serverIp = IPAddress.Parse("72.216.18.77"); // Master Server's IP Address 
     public static TcpClient masterServer = new TcpClient(); 

     private StreamWriter responseWriter; 
     private StreamReader commandReader; 

     private Thread connectionThread; 
     private Thread commandsThread; 

     private bool RequestExitConnectionThread { get; set; } 

     private delegate void AddMessageDelegate(string message, int category); 
     private delegate void ConnectedDelegate(); 

     private bool isConnected { get; set; } 

     public Form1() 
     { 
      InitializeComponent(); 
      isConnected = false; 
     } 

     private void LogMessage(string message, int category) 
     { 
      if (category == 1) 
      { 
       ListViewItem item = new ListViewItem(message); 
       item.BackColor = Color.LightGreen; 
       item.UseItemStyleForSubItems = true; 
       Log.Items.Add(item).SubItems.Add(DateTime.Now.ToString()); 
      } 
      if (category == 2) 
      { 
       ListViewItem item = new ListViewItem(message); 
       item.BackColor = Color.Orange; 
       item.UseItemStyleForSubItems = true; 
       Log.Items.Add(item).SubItems.Add(DateTime.Now.ToString()); 
      } 
      if (category == 3) 
      { 
       ListViewItem item = new ListViewItem(message); 
       item.BackColor = Color.Yellow; 
       item.UseItemStyleForSubItems = true; 
       Log.Items.Add(item).SubItems.Add(DateTime.Now.ToString()); 
      } 
      if (category == 0) 
      { 
       Log.Items.Add(message).SubItems.Add(DateTime.Now.ToString()); 
      } 
     } 

     private void Connected() 
     { 
      LogMessage("Found and Accepted Master Server's connection. Waiting for reply...",1); 
      Status.Text = "Connected!"; 
      Status.ForeColor = Color.Green; 

      commandsThread = new Thread(new ThreadStart(RecieveCommands)); 

      sendClientInfo(); 
     } 

     private void exitButton_Click(object sender, EventArgs e) 
     { 
      Disconnect(); 
      exitButton.Enabled = false; 
      exitButton.Text = "Closing..."; 

      if (connectionThread != null) 
      { 
       while (connectionThread.IsAlive) 
       { 
        Application.DoEvents(); 
       } 
      } 

      this.Close(); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      Connect(); 
     } 

     private void Disconnect() 
     { 
      RequestExitConnectionThread = true; 

      if (masterServer != null) 
       masterServer.Close(); 

      if (connectionThread != null) 
       connectionThread.Abort(); 

      LogMessage("Closing Client. Please wait while Program threads end.", 2); 
     } 

     private void Disconnected() 
     { 
      Status.Text = "Disconnected"; 
      Status.ForeColor = Color.Red; 
      Connect(); 
     } 

     private void Connect() 
     { 
      LogMessage("Attempting to connect to Master Server...", 1); 

      connectionThread = new Thread(new ThreadStart(CreateConnection)); 
      connectionThread.Start(); 
     } 

     private void CreateConnection() 
     { 
      int i = 1; 
      bool success = false; 

      while (!success) 
      { 
       try 
       { 
        using (masterServer = new TcpClient()) 
        { 
         IAsyncResult result = masterServer.BeginConnect(serverIp, MyPort, null, null); 
         success = result.AsyncWaitHandle.WaitOne(1000, false); 
        } 

        if (success) 
        { 
         BeginInvoke(new ConnectedDelegate(this.Connected), new object[] {}); 
         break; 
        } 
        else 
        { 
         Thread.Sleep(2000); 
         BeginInvoke(new AddMessageDelegate(LogMessage), new object[] { "Connection Retry # " + i.ToString() + ". Master Server hasn't been started yet.", 3 }); 
        } 
       } 
       catch 
       { 
        MessageBox.Show("Error!"); 
       } 
       i++; 
      } 

     } 

     private void RecieveCommands() 
     { 
      MessageBox.Show("Hello!"); 
      commandReader = new StreamReader(masterServer.GetStream()); 

      string CommandResponse = commandReader.ReadLine(); 
      string Command = null; 

      if (CommandResponse != null) 
       MessageBox.Show("Recieved Command that was NOT null!"); 

      if (CommandResponse != null) 
      { 
       MessageBox.Show("Recieved null response!"); 
       BeginInvoke(new AddMessageDelegate(LogMessage), new object[] { "Disconnected From Master Server. Reason: Recieved Null response.", 1 }); 
       Disconnected(); 
      } 
      else if (CommandResponse.StartsWith("0")) 
      { 
       MessageBox.Show("Recieved 0 as a response!"); 
       Command = CommandResponse.Substring(2).Trim(); 

       isConnected = false; 
       BeginInvoke(new AddMessageDelegate(LogMessage), new object[] { "Disconnected From Master Server. Reason: " + Command, 1 }); 
      } 
      else if (CommandResponse.StartsWith("1")) 
      { 
       MessageBox.Show("Recieved 1 as a response!"); 
       isConnected = true; 
       BeginInvoke(new AddMessageDelegate(LogMessage), new object[] { "Connected to Master Server Successfully.", 1 }); 
      } 
     } 


     //************************** RESPONSE'S BELOW HERE ************************* \\ 

     private void sendClientInfo() 
     { 
      responseWriter = new StreamWriter(masterServer.GetStream()); 

      responseWriter.WriteLine(myIp.ToString()); 
      responseWriter.Flush(); 
     } 

    } 
} 
+0

「E之前我,除C後」(在關於「你可以在這裏看到任何其他更改或修正」): - ] – 2009-04-27 22:28:01

回答

4

在這種情況下,您不應該使用using塊。事實上,除非出現一些無法想到的狂野場景,否則絕不會在聲明在該範圍之外的變量使用using塊。using塊在塊完成時調用Dispose()方法,這就是您的服務器被丟棄的原因。只需更改您的代碼以刪除該塊,並且應該全部設置。就像這樣:

masterServer = new TcpClient(); 

IAsyncResult result = masterServer.BeginConnect(serverIp, MyPort, null, null); 
success = result.AsyncWaitHandle.WaitOne(1000, false); 
+0

哈哈,感謝。我現在要問另一個問題,關於如何重寫我的masterServer.connect() – OneShot 2009-04-27 22:32:17

相關問題