StreamReader 不会停止读取 C# [英] StreamReader does not stop reading C#

查看:32
本文介绍了StreamReader 不会停止读取 C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Windows 窗体在两台计算机之间建立了 TCP 连接.我有一个整数数组,我使用 XmlSerializer 类对其进行序列化,并使用 StreamWriter 发送它并使用 StreamReader 接收它.
发送:

I have a TCP connection between two computers using windows forms. I have an array of integers which I am serializing using the XmlSerializer class and sending it using the StreamWriter and receiving using StreamReader.
Sending:

NetworkStream stream = m_client.GetStream();   //m_client is a TCPclient
StreamWriter m_writer = new StreamWriter(stream);
int[] a = new int[3] { 10,20,30 };
XmlSerializer serializer = new XmlSerializer(typeof(int[]));
serializer.Serialize(m_writer, a);
//m_writer.Flush();       //Doesn't help
//m_writer.Close();

在接收端:

TcpClient client = (TcpClient)p_client;
NetworkStream stream = client.GetStream();
StreamReader reader = new StreamReader(stream);
if (stream.CanRead)
{
    XmlSerializer serializer = new XmlSerializer(typeof(int[]));
    int[] numbers = (int[])serializer.Deserialize(reader);
    MessageBox.Show(numbers[0].ToString());    //Is not reached
    MessageBox.Show(numbers[1].ToString());
    MessageBox.Show(numbers[2].ToString());
}

问题是接收器上的读取器不会停止读取,除非我终止连接或关闭发送器端的 m_writer(在这种情况下我无法再次使用它来发送).如果它不停止阅读,下一行(即 MessageBox.Show(numbers[0].ToString()))将不起作用.

我需要关于如何通知接收者在 30 岁后停止阅读或如何理解何时停止阅读的建议?


我从 如何在 c# 中通过 TCP 连接发送整数数组
我找到了一个需要终止连接的答案,除非这是唯一可能的方法,否则我宁愿不这样做.XmlSerializer 不会通过 NetworkStream 反序列化

The problem is that the reader on the receiver does not stop reading unless I terminate the connection or close the m_writer on the senders end (in which case I can't use it for sending again). And if it doesn't stop reading, the next line (namely, MessageBox.Show(numbers[0].ToString())) will not work.

I need suggestions on how I can inform the receiver to stop reading after 30 or how can it understand when to stop reading?


I got the XMLserializer idea from How to send integer array over a TCP connection in c#
I found an answer which requires terminating the connection, which I'd rather not do unless it is the only way possible. XmlSerializer Won't Deserialize over NetworkStream

推荐答案

通过 TCP 发送数据时,如果字节流内有任何边界,则由您来定义和实现.

When sending data via TCP, if there are any boundaries within the stream of bytes, it is up to you to define and implement them.

在您的特定示例中,您可以在 XML 数据之前加上字节数似乎是合理的.使用空字节终止数据也是合理的(因为 XML 本身不应该有空字节).无论哪种方式都可以,但恕我直言,基于长度的方法更简单(不需要缓冲额外的未处理数据).

In your particular example, it seems reasonable that you could precede the XML data with a byte count. It would also be reasonable to use a null byte to terminate the data (since the XML itself should never have a null byte). Either way would work but IMHO the length-based approach is somewhat simpler (doesn't require buffering extra unprocessed data).

可能看起来像这样:

NetworkStream stream = m_client.GetStream();   //m_client is a TCPclient
using (MemoryStream buffer = new MemoryStream())
using (StreamWriter writer = new StreamWriter(buffer))
{
    int[] a = new int[3] { 10,20,30 };
    XmlSerializer serializer = new XmlSerializer(typeof(int[]));
    serializer.Serialize(writer, a);

    // This code assumes you aren't sending more than 2GB of XML.
    // This allows the other end to use int instead of long for the
    // length to receive.
    byte[] lengthBytes = BitConverter.GetBytes((int)buffer.Length);

    stream.Write(lengthBytes, 0, lengthBytes.Length);
    buffer.Position = 0;
    buffer.CopyTo(stream);
}

然后接收:

TcpClient client = (TcpClient)p_client;
NetworkStream stream = client.GetStream();

// Using BinaryReader is easier than implementing a correct, blocking read
// of fixed numbers of bytes -- TCP can return as little as a single byte for
// any given receive operation, but BinaryReader insulates us from that.
// Leave the stream open so that we can read more later.
using (BinaryReader binary = new BinaryReader(stream, Encoding.UTF8, true))
{
    int length = binary.ReadInt32();
    byte[] buffer = binary.ReadBytes(length);

    using (MemoryStream streamBuffer = new MemoryStream(buffer))
    using (StreamReader reader = new StreamReader(streamBuffer))
    {
        XmlSerializer serializer = new XmlSerializer(typeof(int[]));
        int[] numbers = (int[])serializer.Deserialize(reader);
        MessageBox.Show(numbers[0].ToString());    //Is not reached
        MessageBox.Show(numbers[1].ToString());
        MessageBox.Show(numbers[2].ToString());
    }
}

(顺便说一句:从技术上讲,MemoryStream 不需要 using,也不需要处理 MemoryStream 对象.但是无论如何,我使用 using ;它给代码增加了很少的开销,并且让我养成了总是处理我创建的流的习惯).

(As an aside: technically one doesn't need using for MemoryStream, or to dispose of a MemoryStream object at all. But I use using anyway; it adds very little overhead to the code, and it keeps me in the habit of always disposing streams that I create).

这篇关于StreamReader 不会停止读取 C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆