2009-04-27 45 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

相关问题