【问题标题】:Most efficient way to receive data on a socket在套接字上接收数据的最有效方式
【发布时间】:2016-10-03 18:42:58
【问题描述】:

我编写了一个连接到远程 IP/端口组合的 VB.Net 应用程序,该组合输出稳定的消息流。 IP 地址可以是 localhost,也可以是远程机器。

远程进程可以随时停止和启动,我的进程需要连接到它并开始接收。两者之间没有关于使用哪些端口的协商。

我当前的代码使用 TcpClient 和 NetworkStream 一次读取一个字节。这将转换为相应的 ASCII 字符(所有消息都是 ASCII 文本)并附加到字符串中,直到收到 EOL 字符。一旦它被添加到要处理的队列中,该字符串被截断并且该过程再次开始。虽然这可行,但一次侦听一个字节可能不是最有效的方法。

我现在正在测试应用程序,但遇到了一些严重的性能问题。尽管我当前的代码有效,但它无法处理抛出的数据量。虽然它每秒可以处理 500 条消息,但它确实在每秒 1500 条消息中挣扎,并在 20% 的 CPU 时达到峰值。

我确定瓶颈是一次读取一个字节的数据 - 有没有办法加快速度?理想情况下,我希望一次读取一行数据,直到收到 EOL 字符,但 TcpClient 中似乎不存在此功能。

套接字编程不是我的强项,所以我可能遗漏了一些明显的东西。救命!

【问题讨论】:

  • 我想说通过 TCP 进行通信的最佳方式是实现message framing,但如果您希望它适合您当前的模型,您也可以使用StreamReader。 -- 请记住,通过实施消息框架,您将同时实施一种识别不同类型数据(例如文本、图像、文件等)的方法。
  • 消息是可变长度的,所以我看不到消息框架是如何工作的——它们只是纯文本,没有花哨的编码。除非我弄错了(我可能是)不是 StreamReader 绑定到本地文件而不是套接字?
  • A StreamReader 是一个reader。它具有从其他流中读取文本的能力。引用文档,StreamReader “以特定编码从字节流中读取字符。”参见one of its constructors。 -- The messages are variable length so I can't see how message framing would work - they are just plain text, no fancy encoding. - 我不明白。 “可变长度”是什么意思?另外,如果他们不使用任何编码,你到底是如何发送他们的?
  • 真的没有“纯文本”这样的东西(手写文本除外)。所有(数字)文本都有某种编码。编码是系统用来将字节转换为字符的表,反之亦然。如果您没有指定任何编码,则使用System.Text.Encoding.Default
  • 抱歉,我的术语有误。字符串是 ASCII - 我认为您是在暗示它们是某种适当的格式。我将再看一下 StreamReader,但我发现的所有示例都没有显示它用于从简单地连接到远程机器的套接字接收数据。不过我已经看了好几个小时了,所以是时候喝杯咖啡来清醒一下了!

标签: vb.net sockets tcp tcpclient


【解决方案1】:

Bytewise IO 通常在教程中展示,因为它非常简单。它不适合生产。

在对套接字进行编程时,请尽可能使用最高级别的抽象。理想情况下,您放弃原始套接字并通过 HTTP 或 websocket 之类的方式请求数据。可用的库。

如果您坚持使用原始套接字,您可以尝试使用StreamReader/Writer 的基于行的格式。不需要 ASCII,只需使用默认的UTF8

读者可以类似这样获取:new StreamReader(new NetworkStream(socket))

【讨论】:

    【解决方案2】:

    尝试使用 System.Text 命名空间中的 ASCIIEncoding.GetString 方法。它应该比一次一个字节的方法更快地将字节数组转换为字符串。

    Dim ascii As New ASCIIEncoding()
    '*** define bytes() byte array here ***
    Dim decoded As String = ascii.GetString(bytes)
    

    此方法还有一个 unicode 变体。

    【讨论】:

    • 这对他有什么帮助?如果他一次得到一个字节,他就会回到他开始的地方。如果他一次获得超过一个字节,他可能在缓冲区中有两条消息的位。
    猜你喜欢
    • 2010-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-24
    • 1970-01-01
    相关资源
    最近更新 更多