【问题标题】:TcpListener does not receive dataTcpListener 收不到数据
【发布时间】:2020-07-26 12:51:34
【问题描述】:

所以我的作业是使用tcp数据包编写一个POP3消息传递软件,并且不允许使用外部库。当我按下连接按钮时,我启动了 tcp 连接,并且我还有一个断开连接按钮来停止它。我用 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();
        }
    }
}

【问题讨论】:

  • Hi Zoltán 欢迎.. 考虑 process 请求并在您的服务器读取循环之后使用(某事)answer,然后将您的 client.Close( ) 之后,而不是在按钮断开连接.. 您现在为每个命令创建一个新的服务器端客户端,而不终止它。
  • 到目前为止,您为调试问题做了哪些工作?你的调查揭示了什么?我觉得这个问题太宽泛了,因为代码中有很多元素看起来有问题,而且没有足够的上下文来说明您需要帮助的具体问题。也就是说,最大的问题之一是您似乎错误地认为您可以重用 Thread 对象。你不能。如果要为每个连接指定一个线程,则每次重新连接时都需要创建一个新线程。
  • @PeterDuniho 我意识到我需要更深入地挖掘以了解更多关于线程的信息。正如你提到的,我为每个连接创建了一个新线程,它解决了这个问题,但现在它在 GetData() 函数中抛出了一个 SocketException。我猜问题是我从另一个线程关闭了 tcp 侦听器,我不知道如何正确关闭它。

标签: c# sockets tcp server client


【解决方案1】:

你能改一下下面的代码吗

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

我的第一个预感是布尔属性没有更新。

【讨论】:

  • 我做了,但问题仍然存在。我为每个连接创建了一个新线程,它解决了这个问题,但这导致我遇到下一个问题,当我调用 server.AcceptTcpClient() 函数时它会抛出一个 SocketException。我认为问题是我在主线程中关闭了 tcp 侦听器,我不知道如何从不同的线程关闭它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-26
  • 2014-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多