【问题标题】:StreamReader doesn't retrieve everything from NetworkStream (TCP and C#)StreamReader 不会从 NetworkStream 中检索所有内容(TCP 和 C#)
【发布时间】:2020-02-19 17:35:02
【问题描述】:

我正在处理一个项目,您必须从服务器检索数据并将其显示在 UI 中。这是一个新闻组服务器,总共包含大约 250 个组。

据我所知,服务器的输出应该存储在 NetworkStream 对象中,并从 StreamReader 中读取,StreamReader 将每一行保存为字符串。

这行得通,但不幸的是,它似乎在完成方法调用之前并没有读完所有内容。

下次我调用另一个命令并从 StreamReader 读取它时,它会返回上一个命令的其余输出。

我已经为此苦苦挣扎了好几个小时,但不知道如何解决这个问题。

这是我的代码:

    public ObservableCollection<Newsgroup> GetNewsGroups()
    {
        ObservableCollection<Newsgroup> newsgroups = new ObservableCollection<Newsgroup>();

        if(connectionStatus.Equals(ConnectionStatus.CONNECTED) && loginStatus.Equals(LoginStatus.LOGGED_IN))
        {

            byte[] sendMessage = Encoding.UTF8.GetBytes("LIST\n");

            // Write to the server 
            ns.Write(sendMessage, 0, sendMessage.Length);
            Console.WriteLine("Sent {0} bytes to server...", sendMessage.Length);

            ns.Flush();

            // b) Read from the server
            reader = new StreamReader(ns, Encoding.UTF8);

            // We want to ignore the first line, as it just contains information about the data
            string test = reader.ReadLine();

            Console.WriteLine(test);

            string recieveMessage = "";

            if (ns.CanRead)
            {

                while (reader.Peek() >= 0)
                {

                    recieveMessage = reader.ReadLine();
                    Console.WriteLine("Got this message {0} back from the server", recieveMessage);
                    // This part will simply remove the annoying numbers after the newsgroup name
                    int firstSpaceIndex = recieveMessage.IndexOf(" ");
                    string refactoredGroupName = recieveMessage.Substring(0, firstSpaceIndex);
                    newsgroups.Add(new Newsgroup { GroupName = refactoredGroupName });
                }

            }

        }

        return newsgroups;

    }

【问题讨论】:

    标签: c# tcp streamreader networkstream nntp


    【解决方案1】:

    我很想看看您在第一行丢弃的数据的哪些信息(“测试”变量中的内容)。如果它告诉您有多少字节到达,您应该使用该信息而不是 Peek 来检索正确的数据量。

    如果最后一行包含一个句点,请将您的 while 循环改为如下所示:

    recieveMessage = reader.ReadLine();
    while (recieveMessage != ".")
    { 
        Console.WriteLine("Got this message {0} back from the server", recieveMessage); // This part will simply remove the annoying numbers after the newsgroup name int 
        firstSpaceIndex = recieveMessage.IndexOf(" "); 
        string refactoredGroupName = recieveMessage.Substring(0, firstSpaceIndex);
        newsgroups.Add(new Newsgroup { GroupName = refactoredGroupName }); 
        recieveMessage = reader.ReadLine();
    }
    

    【讨论】:

    • 哦,它不包含任何有关字节的相关信息。这只是服务器给出的第一行,在这种情况下是:215 个新闻组,形式为“组高低标志”。
    • 列表中发送的最后一个字节数据有什么独特之处吗?大多数行显然都以换行符结尾......我们可以使用的最后一行数据有什么特别之处吗?
    • 您可能不得不使用的一种糟糕方法是,当 Peek 返回 0 时,休眠一段时间,然后再次检查。如果你在一秒钟后没有得到任何东西,那么也许你已经完全完成了。
    • 这只是新闻组的其余部分。我不确定我是否理解正确。例如可能是以下几行: Got this message soc.culture.celtic 0000066255 0000066171 y back from the server Got this message soc.culture.chile 0000157708 0000157643 y back from the server Got this message soc.culture.china 0001020018 0000994871 y back从服务器收到此消息 soc.culture.colombia 0000189192 0000189116 y 从服务器收到此消息 soc.culture.cornish 0000009648 0000009569 y 从服务器返回
    • 知道最后的“y”是什么意思吗?你说如果你再打一个电话,剩下的数据就会在网络流上。这些数据是什么样的?我正在寻找最后一个......就像它可能会在末尾有一个“n”或其他东西而不是一个“y”。您正在阅读此内容的服务器是否可公开访问,以便我可以尝试连接到它?
    猜你喜欢
    • 1970-01-01
    • 2021-03-23
    • 1970-01-01
    • 2020-11-29
    • 1970-01-01
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    • 2016-09-14
    相关资源
    最近更新 更多