C # Como faço para evitar que um objeto TcpClient de dispor em um segmento diferente que eu criei com a nova palavra-chave?

StackOverflow https://stackoverflow.com/questions/795518

Pergunta

Então, eu estou tentando fazer um cliente para o meu servidor em C #, que aceita as mensagens como comandos para que eu possa controlar o cliente remotamente. Eu tive problema após problema com meu masterServer.Connect levando uma eternidade para carregar, e quase toda vez que eu fecho a minha candidatura eu tenho que esperar 10 segundos para ele parar completamente. Já tentei de tudo para acabar com este ... sem sorte. Então eu desisti disso, e agora para corrigir outro problema que estou usando um MasterServer = new TcpClient (), que parece funcionar muito bem dentro do segmento CreateConnection (). Mas quando o fio é feito, eu chamo a algum lugar SendClientInfo () para baixo da linha e isso resulta neste erro de execução:

Não é possível acessar um objeto descartado, System.Net.Sockets.TcpClient

Então, eu tentei o meu melhor para descobrir uma maneira de salvar o objeto antes que dispõe ou nada, mas eu simplesmente não consigo descobrir como fazê-lo. Então, aqui estão minhas perguntas:

  1. Como posso evitar que o mainserver = new TcpClient () de eliminação para que eu possa usar isso no meu SendClientInfo ()?
  2. Alguém pode refazer o meu método CreateConnection () para que eu possa ver como fazer isso correto? Eu reescrevi já que coisa mil vezes, e ainda parece extremamente buggy e do masterServer.connect () leva uma eternidade para fazer se não tiver conectado a um servidor ainda.
  3. Quaisquer outras alterações ou correções que você pode ver aqui. Estive dentro e fora isso por horas e horas apenas tentando me ensinar como usar Sockets através da leitura como uma centena de tutoriais. Qualquer coisa que você me que estou fazendo de errado Eu sempre me lembrarei mostrar e fazê-lo corretamente na próxima vez.

Deixe-me saber se você precisar de mais informações ... eu realmente aprecio isso.

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();
        }

    }
}
Foi útil?

Solução

Neste caso, você não deve estar usando um bloco using. Na verdade, a menos que existam alguns cenários selvagens que não vêm à mente, nunca use um bloco using em uma variável que é declarada fora desse âmbito. O bloco using chama o método Dispose() na conclusão do bloco, razão pela qual o servidor está sendo descartado. Basta alterar seu código para remover o bloco e você deve estar tudo pronto. Como esta:

masterServer = new TcpClient();

IAsyncResult result = masterServer.BeginConnect(serverIp, MyPort, null, null);
success = result.AsyncWaitHandle.WaitOne(1000, false);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top