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

标签 c# network-programming tcpclient networkstream binaryreader

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

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

有没有一种简单的方法可以确定从 NetworkStream 中读取(或写入)的字节数,而不必通过箍来计算传输的字符串的实际字节长度?

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

另请注意,NetworkStream 不支持 Position 属性,因为它提示无法Seek

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

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

最佳答案

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

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

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

关于c# - 计算 TcpClient 通过 NetworkStream BinaryReader/BinaryWriter 传输的字节数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34273942/

相关文章:

java - 网络 TCP 客户端连接

c# - 使用 TCP 文件传输客户端发送时出现问题

c# - 使用 C# 迭代具有相同名称的表单字段

linux - 如何在网络上编写音频/视频应用程序?

java - 如何使用输入流java的markSupported特性

java - 在 RFB 协议(protocol)中提交 (x,y) 位置

c# - 如何在与 SignalGo 套接字断开连接后自动调用登录功能

c# - 在 C# 测试装置中从 Nunit3 获取参数

c# - .NET WebBrowser 控件 javascript

c# - LINQ查询参数可以为空