TcpListener не получает данные - PullRequest
0 голосов
/ 14 апреля 2020

Итак, моя домашняя работа - написать программное обеспечение для обмена сообщениями POP3 с использованием пакетов tcp, и мне не разрешено использовать внешние библиотеки. Я запускаю tcp соединение, когда нажимаю кнопку Connect, и у меня также есть кнопка Disconnect, которая останавливает его. Я протестировал свою серверную программу с PuTTY, и она работает нормально после первого подключения, но когда я нажимаю Отключить и снова подключить, он не выводит полученные данные на монитор. Эта проблема беспокоит меня целую вечность, пожалуйста, помогите. Вот мой код:

Редактировать: Проблема была в том, что я не совсем понимаю, как работают потоки, и я не создавал новый поток для каждого соединения, поэтому я создавал новый поток каждый раз, когда создавал новый слушатель.

namespace POP3Server
{
    public partial class MainWindow : Window
    {
        private TcpListener server;
        private Int32 port;
        private IPAddress ipAddress;
        private TcpClient client;
        private Logger log;
        private Thread tcpAcceptThread;
        private bool serverStarted;

        public MainWindow()
        {
            InitializeComponent();

            log = new Logger(txtConsole);

            serverStarted = false;
            tcpAcceptThread = new Thread(GetData);
        }

        private void btnConnect_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                port = Convert.ToInt32(txtPort.Text);
                ipAddress = IPAddress.Parse(txtIP.Text);
                server = new TcpListener(ipAddress, port);
                server.Start();

                if (tcpAcceptThread.ThreadState != ThreadState.Unstarted)
                    tcpAcceptThread.Start();

                serverStarted = true;
                log.WriteLine("Server started!");

                btnConnect.IsEnabled = false;
                btnDisconnect.IsEnabled = true;
            }
            catch (Exception ex)
            {
                log.WriteLine(ex.ToString());
            }
        }

        private void btnDisconnect_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (client != null)
                    client.Close();
                server.Stop();

                log.WriteLine("Server stopped!");
                serverStarted = false;

                btnConnect.IsEnabled = true;
                btnDisconnect.IsEnabled = false;
            }
            catch (Exception ex)
            {
                log.WriteLine(ex.ToString());
            }
        }

        private void GetData()
        {
            try
            {
                while (serverStarted)
                {
                    client = server.AcceptTcpClient();
                    this.Dispatcher.Invoke(() => log.WriteLine("Connected!"));

                    Byte[] bytes = new Byte[256];
                    String data = null;

                    NetworkStream stream = client.GetStream();

                    int i;

                    // Loop to receive all the data sent by the client.
                    while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
                    {
                        // Translate data bytes to a ASCII string.
                        data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
                        this.Dispatcher.Invoke(() => log.WriteLine("Received: " + data));
                    }
                }
            }
            catch (Exception ex)
            {
                this.Dispatcher.Invoke(() => log.WriteLine(ex.ToString()));
            }
        }

        private void btnClear_Click(object sender, RoutedEventArgs e)
        {
            log.Clear();
        }
    }
}

1 Ответ

0 голосов
/ 14 апреля 2020

Не могли бы вы изменить следующий код

private bool serverStarted;

на:

private object _someLockObject = new object();
private bool _serverStarted = false;

private bool serverStarted {
get {
  lock (_someLockObject)
  {
    return _serverStarted;
  }
}
set {
  lock (_someLockObject)
  {
    _serverStarted = value;
  }
}
};

Моя первая догадка - логическое свойство не обновлено.

...