Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 计算TcpClient通过NetworkStream BinaryReader/BinaryWriter传输的字节数_C#_Network Programming_Tcpclient_Networkstream_Binaryreader - Fatal编程技术网

C# 计算TcpClient通过NetworkStream BinaryReader/BinaryWriter传输的字节数

C# 计算TcpClient通过NetworkStream BinaryReader/BinaryWriter传输的字节数,c#,network-programming,tcpclient,networkstream,binaryreader,C#,Network Programming,Tcpclient,Networkstream,Binaryreader,我正在使用围绕TcpClient构建的网络协议,使用BinaryReader从底层NetworkStream读取字节(相反,使用BinaryWriter写入) 协议以UTF-8编码传输字符串,并调用reader.ReadString()从流中读取字符串(使用writer.Write(someStr)进行写入) 有没有一种简单的方法来确定从网络流读取(或写入)的字节数,而不必跳转来计算传输字符串的实际字节长度 请注意,BinaryWriter.Write()在字符串的实际字节之前写入一个7位编码的

我正在使用围绕
TcpClient
构建的网络协议,使用
BinaryReader
从底层
NetworkStream
读取字节(相反,使用
BinaryWriter
写入)

协议以UTF-8编码传输字符串,并调用
reader.ReadString()
从流中读取字符串(使用
writer.Write(someStr)
进行写入)

有没有一种简单的方法来确定从网络流读取(或写入)的字节数,而不必跳转来计算传输字符串的实际字节长度

请注意,
BinaryWriter.Write()
在字符串的实际字节之前写入一个7位编码的整数,这使得任何手动计算都更加复杂

还请注意,
NetworkStream
不支持
Position
属性,因为它抱怨无法
Seek

此外,我希望避免在读/写过程中引入必须复制/扫描数据的中介,以免影响整个系统的性能


是否有一种简单、高级的方法可以计算通过网络接口的字节数,而无需手动计算字符串的编码和长度?

您可以在networkstream和计算字节数的读卡器之间插入自定义流


这样做不需要复制数据。只需将经过的字节数添加到计数器。

对于那些对我如何实现字节计数流感到好奇的人,这里是它的全部荣耀(或耻辱,视情况而定):

使用系统;
使用System.IO;
名称空间流
{
/// 
///用于跟踪读写字节数的包装器。
/// 
公共类字节计数流:流
{
私有只读流内部;
私人长字节;
私有长字节读取;
公共字节计数流(流内部)
{
this.inner=内部;
}
公共覆盖无效刷新()
{
内平齐();
}
公共覆盖长寻道(长偏移,参见原始坐标系)
{
抛出新的NotImplementedException();
}
公共覆盖无效设置长度(长值)
{
抛出新的NotImplementedException();
}
公共重写整型读取(字节[]缓冲区、整型偏移量、整型计数)
{
int readBytes=inner.Read(缓冲区、偏移量、计数);
totalBytesRead+=读取字节;
返回readBytes;
}
公共重写无效写入(字节[]缓冲区、整数偏移量、整数计数)
{
写(缓冲区、偏移量、计数);
TotalBytesWrited+=计数;
}
public override bool CanRead=>true;
公共覆盖boolcanseek=>false;
public override bool CanWrite=>true;
公共覆盖长长度
{
得到
{
抛出新的NotImplementedException();
}
}
公共重写长位置{get;set;}
public long TotalBytesWrited=>TotalBytesWrited;
公共长TotalBytesRead=>TotalBytesRead;
}
}

实现将缓冲区传递给底层流,因此实际上不涉及数据复制。

这样做您希望实现什么?您可以在networkstream和计算字节数的读取器之间插入自定义流。@usr我只需要知道读取/写入的总字节数-用于报告目的。底层协议堆栈中的某些内容必须知道发送/接收的字节数。。。我想以最简单的方式获得这些信息。你能举出一个例子来说明如何做到这一点吗?有什么具体问题吗?从流派生并以这种方式包装另一个流实例。这难道不需要缓冲数据吗?我不想让事情慢下来。我已经说过不会有缓冲。如果您不认为这是真的,请提供一个为什么会有缓冲的原因。也许您应该开始使用流实现,以便了解它的外观。例如,在Read方法中,您将传入的缓冲区传递给内部流。我说我想要一种简单的方法。虽然创建自定义流并不可怕——你说得对,它比我想象的要简单:—)——但确保它在以前使用
NetworkStream
的所有地方都使用是一个大麻烦。这不是我一直在寻找的简单解决方案,但它是有效的,所以我会接受你的答案。谢谢。
Length
看起来破了。这不总是返回0吗?应该扔,位置也是。我几乎用新的简洁6.0语法忽略了它。我需要习惯这一点。而且,我认为,如果不进行处理,这类课程是相当危险的。
using System;
using System.IO;

namespace Streams
{
    /// <summary>
    /// A wrapper around a <see cref="Stream"/> that keeps track of the number of bytes read and written.
    /// </summary>
    public class ByteCountingStream : Stream
    {
        private readonly Stream inner;

        private long totalBytesWritten;
        private long totalBytesRead;


        public ByteCountingStream(Stream inner)
        {
            this.inner = inner;
        }

        public override void Flush()
        {
            inner.Flush();
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            throw new NotImplementedException();
        }

        public override void SetLength(long value)
        {
            throw new NotImplementedException();
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            int readBytes = inner.Read(buffer, offset, count);
            totalBytesRead += readBytes;
            return readBytes;
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            inner.Write(buffer, offset, count);
            totalBytesWritten += count;
        }

        public override bool CanRead => true;
        public override bool CanSeek => false;
        public override bool CanWrite => true;

        public override long Length
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        public override long Position { get; set; }

        public long TotalBytesWritten => totalBytesWritten;
        public long TotalBytesRead => totalBytesRead;
    }
}