使用 Read::read_to_string 从 TcpStream 读取会挂起,直到远程端关闭连接

2024-04-18

我正在尝试实施Haskell IRC 机器人教程 https://wiki.haskell.org/Roll_your_own_IRC_bot在 Rust 中,我在阅读连接后服务器发送给我的内容时遇到一些困难。似乎发生的情况是,我连接并从服务器读取约 5 KB 的内容,然后大约 240 秒后,所有内容都会立即转储,而不是逐行读取。连接因 ping 超时而关闭,这最终应该发生,因为我还没有可以回复的 ping-pong 函数。

这是我到目前为止所拥有的:

use std::io::{Read, Write};
use std::net::TcpStream;

fn main() {
    let mut stream = TcpStream::connect("irc.freenode.org:6667").unwrap();

    let _ = stream.write(b"NICK G-SERUFU\r\n");
    let _ = stream.write(b"USER G-SERUFU 0 * :brobot\r\n");
    let _ = stream.write(b"JOIN #tutbot-testing\r\n");

    let mut line = String::with_capacity(512);
    loop {
        let result = stream.read_to_string(&mut line);
        match result {
            Ok(n) => println!("Received {} bytes", n),
            _ => {}
        }
        line.clear();
    }
}

当我修改循环 a 以使用数组而不是字符串时,我立即得到我期望的输出:

let mut line;
loop {
    line = [0; 512];
    let result = stream.read(&mut line);
    match result {
        Ok(n) => println!("Received {} bytes",n),
        _ => {},
    }
}

我的结论是stream.read_to_string(&mut line)某种程度上是罪魁祸首。为什么会这样呢?有什么明显的事情是我忽略的吗?

更具体地说,在第一种情况下,输出会在 ping 超时后出现,并打印以下内容:

//Around 4 minutes elapse before anything is printed to console
Received 5323 bytes
Received 0 bytes
Received 0 bytes
Received 0 bytes
//Continues to print "Received 0 bytes" since the connection has closed but I haven't broken out of the infinite loop

在使用数组的第二种情况下,我几乎立即收到正确的输出:

Received 64 bytes
Received 51 bytes
Received 512 bytes
Received 512 bytes
Received 350 bytes
Received 512 bytes
Received 512 bytes
...

查看文档用于Read::read_to_string https://doc.rust-lang.org/std/io/trait.Read.html#method.read_to_string,强调我的:

读取所有字节直到文件结束在此源中,将它们放入buf.

同样对于Read::read_to_end https://doc.rust-lang.org/std/io/trait.Read.html#method.read_to_end:

读取所有字节直到文件结束在此源中,将它们放入buf.

值得注意的是,你没有阅读512在第一个示例中,您预先分配了 512 字节的空间,然后读取every字节直到套接字关闭 - 4 分钟后。

听起来你想使用BufRead::read_line https://doc.rust-lang.org/std/io/trait.BufRead.html#method.read_line:

读取所有字节,直到到达换行字节(0xA 字节),并将它们附加到提供的缓冲区。

该函数将继续从底层流读取(并缓冲)字节,直到找到换行符(0xA 字节)或 EOF。一旦找到,直到并包括分隔符(如果找到)的所有字节都将被附加到 buf。

您还可以使用任何其他在返回之前读取固定量数据的技术。一个这样的例子是Read::take https://doc.rust-lang.org/std/io/trait.Read.html#method.take,这将限制您一次可以读取的字节总数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Read::read_to_string 从 TcpStream 读取会挂起,直到远程端关闭连接 的相关文章

随机推荐

  • Spring MVC application.properties 不会被配置文件 application-dev.properties 覆盖

    我正在寻找一种根据 JVM 环境变量配置不同 application properties 文件的方法 我在 Spring 参考资料中找到了这个文档 除了 application properties 文件之外 还可以使用命名约定 appl
  • C# 中的异常有多昂贵?

    C 中的异常有多昂贵 只要堆栈不深 它们似乎并不会非常昂贵 然而我读到了相互矛盾的报道 有没有没有被反驳的明确报告 读到异常在性能方面代价高昂后 我编写了一个简单的测量程序 与该程序非常相似乔恩 斯基特 多年前发表 https web ar
  • 如何从 OsStr 和 str 组件构建 URL?

    此代码遍历文件夹 并查找以以下结尾的文件 txt 接下来 我想采取entry file name 这是属于std ffi os str OsStr输入 并将其加入BASE URL来形成一个 URL const FOLDER NAME str
  • 更改文件名后缀(使用 sed ?)

    我想改变文件名后缀来自文件 使用 bash 脚本 但有时有些文件带有一个句点 有些文件带有两个句点 现在我用这个 new file echo file sed s log suf 1 num 其中 new file 是新文件名 file 是
  • OMP_NUM_THREADS=1 时 #pragma ompatomic 的性能问题

    我观察到我正在编写的 openmp 代码出现了意外的 对我来说 行为 代码结构如下 pragma omp parallel for for int i 0 i
  • 真的有类似 Objective C++ 的东西吗?

    我正在读一本post http savoysoftware com blog p 114关于 iPhone 编程 我注意到关于 Objective C 的讨论 帖子中显示的代码看起来主要像 Objective C 但也有一些 C 代码片段
  • 如何将 Quickbooks 桌面应用程序与 PHP(网络应用程序)集成?

    在我的应用程序中 我想使用 php 通过 PHP 集成 QuickBooks 因此 我想从网络服务器 使用PHP 调用QuickBooks桌面版应用程序来推送数据和检索数据 我被困在这里了 我不知道从哪里开始 有人让我从 webconnec
  • 通用应用程序,适用于 iPhone 的纵向方向和 iPad 的横向方向

    我正在使用 Swift 创建一个通用应用程序 我使用过故事板和自动布局 要求是创建一个通用应用程序 仅支持 iPhone 的纵向方向和仅 iPad 的横向方向 我已经为 iPhone 开发了 UI 现在我将开始开发 iPad UI 此外 为
  • 温莎城堡生活方式问题

    我正在实现hangFire 它是我的项目中的一个作业调度库 我面临着与此相同的问题link https stackoverflow com questions 11873905 castle windsor lifestyle depend
  • 使用 for..of 迭代时删除 Set 中的元素是否安全?

    是否指定可以删除实例中的任意元素Set迭代时使用for of然后 你不会在一个元素上迭代多次 除了删除的元素之外 您不会错过迭代开始时集合中的任何其他元素 Yes 在迭代集合时添加元素和删除元素是完全可以的 JavaScript 2015
  • 分析 Windbg 中 !threadpool 和 !threads 的输出

    我已经在四台服务器上生成了转储 并正在分析 threadpool 和 threads 的输出 我注意到以下输出大致一致 0 024 gt threadpool CPU utilization 0 Worker Thread Total 2
  • 在 silverlight 中保存文件和异步回调

    在 Silverlight 中 您必须使用保存文件对话框来保存文件 您只能通过用户事件 即按钮单击 打开此对话框 我从 Web 服务调用异步返回文件数据 我如何将其保存到文件 如果我在服务调用之前询问他们 我将无法在数据返回后使用该流 如果
  • OpenJDK 8:无法解析主机名

    我正在尝试奔跑slf4j with log4jopenJDK 8 上的 2 8 Ubuntu 上的最新版本8u131 b11 0ubuntu1 17 04 1 当通过 maven openjdk 运行简单的 java 类时 无法解析本地主机
  • 如何读取cassandra数据而不区分大小写

    我需要从 cassandra 获取数据而不区分大小写 请帮我 Cassandra 中没有区分大小写的概念 所有数据都存储为byte 所以它甚至不是一个字符串 您可以制作自定义比较器 参见API http wiki apache org ca
  • 如何在 Excel 中根据验证结果进行条件格式设置?

    如果单元格无效 我想更改单元格的格式 在这种情况下 有效 意味着单元格未通过数据验证规则 我问这个问题是因为我在SO上找不到答案 我最终解决了它 我将发布我的答案 看看人们是否愿意发表评论或提供更好的答案 这是一个基本大纲 我想在本周晚些时
  • 局部变量和全局变量默认是如何初始化的?

    根据以下内容 我对吗 global A 引用被初始化为 null global int 为 0 local A 引用为空 local int 未初始化 global A x 和 local A x 均未初始化 谢谢你的帮助 A global
  • 如何在 IDE 中使用 Grails 依赖项

    So I finally https stackoverflow com questions 1867064 grails and local maven dependencies让我的依赖项与 Grails 一起工作 现在 我的 IDE
  • 如何创建行列总和为 1 和 0 的对称矩阵

    我试图找到一种优雅的算法来创建 1 和 0 的 N x N 矩阵 但有以下限制 每行每列之和必须为Q 可自由选择 对角线必须是 0 矩阵必须是对称的 矩阵不一定是随机的 然而 随机和非随机解都很有趣 因此对于 Q 偶数 只需使每一行成为向量
  • Spring验证字符串值是JSON

    我的配置文件中有一些值 它应该是 JSON 它将作为字符串加载 我希望 Spring 在注入之前验证该值确实是有效的 JSON 否则会抛出错误 我已经阅读了现有的验证注释 例如 NotNull Size Min Max Email NotE
  • 使用 Read::read_to_string 从 TcpStream 读取会挂起,直到远程端关闭连接

    我正在尝试实施Haskell IRC 机器人教程 https wiki haskell org Roll your own IRC bot在 Rust 中 我在阅读连接后服务器发送给我的内容时遇到一些困难 似乎发生的情况是 我连接并从服务器