2009-04-27 3 views
0

Итак, я пытаюсь сделать клиент для своего сервера на C#, который принимает сообщения как команды, чтобы я мог удаленно управлять клиентом. У меня возникла проблема после проблемы с моим masterServer.Connect с загрузкой FOREVER, и почти каждый раз, когда я закрываю приложение, я должен ждать 10 секунд, чтобы он полностью остановился. Я пробовал ВСЕ остановить это ... не повезло. Поэтому я отказался от этого, и теперь, чтобы исправить еще одну проблему, я использую masterServer = новый TcpClient(), который, похоже, очень хорошо работает внутри потока CreateConnection(). Но когда нить будет сделано, я называю SendClientInfo() где-то вниз по линии, и это приводит к ошибке во время выполнения:C# Как предотвратить удаление объекта TcpClient в другом потоке, который я создал с помощью нового ключевого слова?

Не удается получить доступ к объекту, расположенную, System.Net.Sockets.TcpClient

Поэтому я попытался изо всех сил выяснить способ сохранения объекта до его размещения или чего-либо другого, но я просто не могу понять, как это сделать. Итак, вот мои вопросы:

  1. Как предотвратить удаление утилиты mainServer = new TcpClient(), чтобы я мог использовать ее в моем SendClientInfo()?
  2. Может ли ANIONE переработать мой метод 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

«я перед тем е, за исключением после того, как с» (в отношении «Любые другие изменения или исправления ошибок вы можете увидеть здесь»): -] –

ответ

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

 Смежные вопросы

  • Нет связанных вопросов^_^