c recv() 读取直到出现换行符

2023-11-24

我正在用 C 语言编写 IRC 机器人,但遇到了障碍。

在我的主函数中,我创建了套接字并连接,所有这些快乐的事情。然后我有一个(几乎)无限循环来读取从服务器发回的内容。然后我将读取的内容传递给辅助函数,processLine(char *line)- 问题是,以下代码读取直到我的缓冲区已满 - 我希望它只读取文本,直到出现换行符(\n)或回车符(\r)(从而结束该行)

   while (buffer[0] && buffer[1]) {
        for (i=0;i<BUFSIZE;i++) buffer[i]='\0';
        if (recv(sock, buffer, BUFSIZE, 0) == SOCKET_ERROR)
            processError();

        processLine(buffer);
    }

最终发生的情况是许多线路都卡在一起,当这种情况发生时我无法正确处理线路。

如果您不熟悉 IRC 协议,简单总结一下,当发送消息时,它通常如下所示::YourNickName!YourIdent@YourHostName PRIVMSG #someChannel :The rest on from here is the message sent...例如,登录通知是这样的::the.hostname.of.the.server ### bla some text bla其中 ### 是用于处理的代码(?) - 即 372 是一个指示符,表明以下文本是每日消息的一部分。

当它们都挤在一起时,我无法读取哪一行的数字,因为我找不到一行的开始或结束位置!

非常感谢您对此的帮助!

P.S.:这是在 Linux 上编译/运行的,但我最终想将它移植到 Windows,所以我尽可能多地利用它来实现多平台。

P.S.S.:这是我的 processLine() 代码:

void processLine(const char *line) {
    char *buffer, *words[MAX_WORDS], *aPtr;
    char response[100];
    int count = 0, i;
    buffer = strdup(line);

    printf("BLA %s", line);

    while((aPtr = strsep(&buffer, " ")) && count < MAX_WORDS)
        words[count++] = aPtr;
        printf("DEBUG %s\n", words[1]);
    if (strcmp(words[0], "PING") == 0) {
        strcpy(response, "PONG ");
        strcat(response, words[1]);
        sendLine(NULL, response); /* This is a custom function, basically it's a send ALL function */
    } else if (strcmp(words[1], "376") == 0) { /* We got logged in, send login responses (i.e. channel joins) */
        sendLine(NULL, "JOIN #cbot");
    }
}

处理这个问题的通常方法是recv到应用程序中的持久缓冲区中,然后拉出一行并处理它。稍后您可以在调用之前处理缓冲区中的剩余行recv再次。请记住,缓冲区中的最后一行可能仅被部分接收;你必须通过重新输入来处理这种情况recv完成该行。

这是一个示例(完全未经测试!还寻找一个\n, not \r\n):

#define BUFFER_SIZE 1024
char inbuf[BUFFER_SIZE];
size_t inbuf_used = 0;

/* Final \n is replaced with \0 before calling process_line */
void process_line(char *lineptr);
void input_pump(int fd) {
  size_t inbuf_remain = sizeof(inbuf) - inbuf_used;
  if (inbuf_remain == 0) {
    fprintf(stderr, "Line exceeded buffer length!\n");
    abort();
  }

  ssize_t rv = recv(fd, (void*)&inbuf[inbuf_used], inbuf_remain, MSG_DONTWAIT);
  if (rv == 0) {
    fprintf(stderr, "Connection closed.\n");
    abort();
  }
  if (rv < 0 && errno == EAGAIN) {
    /* no data for now, call back when the socket is readable */
    return;
  }
  if (rv < 0) {
    perror("Connection error");
    abort();
  }
  inbuf_used += rv;

  /* Scan for newlines in the line buffer; we're careful here to deal with embedded \0s
   * an evil server may send, as well as only processing lines that are complete.
   */
  char *line_start = inbuf;
  char *line_end;
  while ( (line_end = (char*)memchr((void*)line_start, '\n', inbuf_used - (line_start - inbuf))))
  {
    *line_end = 0;
    process_line(line_start);
    line_start = line_end + 1;
  }
  /* Shift buffer down so the unprocessed data is at the start */
  inbuf_used -= (line_start - inbuf);
  memmove(innbuf, line_start, inbuf_used);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c recv() 读取直到出现换行符 的相关文章

  • 什么定义了类型的大小?

    ISO C 标准规定 sizeof char lt sizeof short lt sizeof int lt sizeof long 我在 BIT Linux mint 19 1 上使用 GCC 8 大小为long int is 8 我正
  • 无法使用c#更改视频捕获分辨率

    我正在尝试使用 C 中的 DirectShowNet 更改默认网络摄像头分辨率 据我所知 我需要通过调用 windows win32 api dll 中内置的 VideoInfoHeader 类来更改它以进行 avi 捕获 我有来自 Dir
  • Boost MPI 在监听列表时不会释放资源?

    这是一个后续问题如何释放 boost mpi request https stackoverflow com questions 44078901 how do i free a boostmpirequest 我在监听列表而不是单个项目时
  • C# 中类似图的实现

    所以我有一个对象 我们称之为 Head 它有一个对象列表 C C1 C2 C3 T T1 T2 和 M M1 M2 并且所有这些都是相互关联的 例如 Head gt C1 C2 C3 T1 T2 M1 M2 T1 gt C1 C2 T2 g
  • 如何通过 libwebsocket 发送异步数据?

    我正在将 Warmcat 的 libwebsocket C 库用于小型 Websocket 服务器 我已经启动并运行了这些示例 并且可以发送数据以响应从 websocket 接收数据 例如回显发送的反向字节 但是 我无法弄清楚如何在不使用
  • C# 中 PKCS11Interop 库的线程安全使用 [已关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在使用 PKCS11Interop 在 HSM 内执行密钥管理操作 我使用的 HSM 是 Thales PCI Express 下面是
  • 选择initializer_list迭代器定义

    Why std initializer list
  • 在 .NET Core 中从 HttpResponseMessage 转换为 IActionResult

    我正在将之前在 NET Framework 中编写的一些代码移植到 NET Core 我有这样的事情 HttpResponseMessage result await client SendAync request if result St
  • QSpinBox 输入 NaN 作为有效值

    我正在尝试扩展 QSpinBox 以能够输入 NaN 或 nan 作为有效值 根据文档 我应该使用 textFromValue valueFromText 和 validate 函数来完成此操作 但我无法让它工作 因为它仍然不允许我输入除数
  • 查找方法不适用于 EF6.1 模拟

    我已经使用这些 msdn 指南设置了模拟 使用模拟框架进行测试 EF6 及以上 http msdn microsoft com en us data dn314429 var bsAc db BusAcnts FirstOrDefault
  • 本地时间的内存需要释放吗?

    void log time t current time 0 tm ptm localtime current stuf 只是想确定 我是否需要在方法结束时释放 tm 指针分配的内存 不 你不应该释放它 该结构是静态分配的 检查文档 htt
  • linq where 子句和 count 导致 null 异常

    除非 p School SchoolName 结果为 null 否则下面的代码将起作用 在这种情况下 它会导致 NullReferenceException if ExistingUsers Where p gt p StudentID i
  • 从 C# 调用时无法识别 Powershell 命令

    这是这个的延续Question https stackoverflow com questions 66280000 powershell object returns null 66280138 noredirect 1 comment1
  • 在 C# .NET 中对非 ASCII 字符进行编码

    我想向我的应用程序发送的电子邮件添加自定义标头 标头名称只能包含 ASCII 字符 但对于值和用户可能会输入 UTF 8 字符 我必须对它们进行 Base64 编码 此外 我还必须将它们解码回 UTF 8 以便在 UI 中向用户显示它们 最
  • 在特定线程上运行工作

    我想要一个特定的线程 任务队列并在该单独的线程中处理任务 应用程序将根据用户的使用情况创建任务并将其排队到任务队列中 然后单独的线程处理任务 即使队列为空 保持线程活动并使用它来处理排队任务也至关重要 我尝试过几种实现TaskSchedul
  • 如何重用具有稍微不同的 ProcessStartInfo 实例的 Process 实例?

    我有以下开始的代码robocopy https technet microsoft com en us library cc733145 aspx as a Process 我还需要进行数据库查询以确定每次需要复制哪些目录robocopy被
  • 为什么 C++ 标准没有将 sizeof(bool) 定义为 1?

    Size of char signed char and unsigned char由 C 标准本身定义为 1 个字节 我想知道为什么它没有定义sizeof bool also C 03 标准 5 3 3 1 说 sizeof char s
  • Unity - 在生成时获取随机颜色

    我有一个小问题 我想在我的场景中生成四边形 它们都应该有红色或绿色作为材质 但 Random Range 函数只能是 int 我该如何解决它 void SpawningSquadsRnd rndColor 0 Color red rndCo
  • 使用C标准数学库精确计算标准正态分布的CDF

    标准 C 数学库不提供计算标准正态分布 CDF 的函数 normcdf 然而 它确实提供了密切相关的函数 误差函数 erf 和互补误差函数 erfc 计算 CDF 的最快方法通常是通过误差函数 使用预定义常量 M SQRT1 2 来表示 d
  • 如何根据当前日期时间发现财政年度?

    我需要基于当前或今天的日期时间的财政年度 假设我们认为今天的日期是10 April 2011 那么我需要输出为Financial Year 2012在某些情况下 我需要以短格式显示相同的输出FY12 我想以两种方式显示 在我们的要求中 考虑

随机推荐

  • TypeScript 或 JavaScript 类型转换

    如何处理 TypeScript 或 Javascript 中的类型转换 假设我有以下 TypeScript 代码 module Symbology export class SymbolFactory createStyle symbolI
  • 在 Web Api 聊天应用程序后端服务器中使用或不使用数据传输对象 (DTO)

    我有一个使用 Web Api 构建的聊天应用程序后端 我在其中直接向客户端公开多个数据库实体 我想知道将实体映射到 DTO 是否有任何积极意义 或者我应该继续像目前一样公开这些实体 只是为了澄清 我不是在问 DTO 与非 DTO 的一般问题
  • 为 Umbraco 设置本地开发环境

    我继承了一个 Umbraco CMS 项目 Umbraco 实例和自定义用户控件存在于我们的测试服务器上 因为初始构建已经向客户端进行了演示 我现在需要承担这个任务 初始构建是由一名自由开发人员在我来这里之前完成的 并且不存在有关设置 部署
  • 如何将 Subversion 存储库发布到本地 IIS?

    在工作中 我们有一台安装了 IIS 和 Subversion 的 Windows Server 2003 我们用它在本地发布和测试 我们的 ASP NET 网站 每个程序员都在他的 PC 上安装了 Tortoise 并且可以更新 提交内容到
  • 如何在 OSX 中点击/挂钩键盘事件并记录哪个键盘触发每个事件

    我现在已经发现了如何在 OS X 上低级别挂接 点击键盘事件 如何在 MacBook 键盘上点击 钩住 F7 到 F12 以及电源 弹出 打印出该答案的代码 compile and run from the commandline with
  • 如何添加不同大小和颜色的ggplot2字幕?

    我正在使用 ggplot2 来改进降水条形图 这是我想要实现的目标的可重现示例 library ggplot2 library gridExtra secu lt seq 1 16 by 2 melt d lt data frame y s
  • 选择,具有收缩属性的 OutlineInput 标签在空时与 TextField 不同

    如果我使用 TextField 组件 并设置 InputLabelProps shrink true 则标签将保留在 TextField 的顶部 并且轮廓将被剪切以正确显示标签 但是 如果我使用 Select 组件 如下所示
  • 如何选择sql中除一列之外的所有列? [复制]

    这个问题在这里已经有答案了 可能的重复 SQL 使用 SELECT except columnA FROM tableA 排除列 是否可以选择除一列之外的所有列 这是所有列名称 id name address age SELECT id n
  • Android - 如果没有互联网连接则显示一条消息并继续检查

    我已经为此工作了几天了 我刚刚开始使用 Android 我有一个由两部分组成的问题 我想检查互联网是否可用 如果启动 webView 则不发出警报并阻止 webView 加载 我已经尝试过此操作 但如果没有互联网连接 例如飞行模式 它会强制
  • 如何判断秋千上的窗户是否打开

    我的应用程序有一个问题 用户一次会打开多个窗口 我添加了 dispose 方法来调用关闭窗口 现在我应该始终保持至少一个窗口打开 以便应用程序在没有完全关闭的情况下不会隐藏 如果你不明白 请阅读以下场景 我同时打开了窗口 A 和窗口 B 现
  • 使用 FileZilla 上传到 SFTP 服务器时收到描述为“失败”的失败

    我多次遇到这个问题 从 FileZilla 上传或编辑任何文件时 它显示错误消息 错误 写入时出错 收到描述为 失败 的失败 上传文件后 文件大小将为 0 字节 我的服务器是 AWS EC2 具有最小实例类类型 The 失败 是错误代码 4
  • std::unordered_set 是否连续(如 std::vector)?

    我将指针存储在 std unordered set 中 我这样做是因为我不想要任何重复项 我删除集合中的指针 因此如果存在重复项 我将尝试删除已删除的指针 我大量循环遍历这些集合 并且因为我知道 std vector 是最快的循环容器 连续
  • 不同命名空间中模板的特化

    我正在使用 C 开发一个跨平台库 MSVC 编译得很好 但 g 给我带来了问题 假设我有以下 Enum 辅助类 File Enum h ifndef ENUM H define ENUM H include
  • javascript正则表达式匹配特定域名

    我一直在尝试制作一个正则表达式来将 URL 与特定域名相匹配 所以如果我想检查这个网址是否来自 example com 什么 reg exp 应该是最好的 此 reg exp 应匹配以下类型的 URL http api example co
  • 如何在新标签页上打开谷歌广告?

    每当访问者点击网站上的 Google 广告时 该广告就会在同一页面中打开 从而取代我的网站 我就会失去该访问者 我们是否可以采取一些措施 以便每当网站访问者点击 Google 广告时 它就会在新标签中打开 有什么脚本需要修改吗 我尝试了一个
  • MongoDB:具有稀疏值的唯一稀疏复合索引

    我正在尝试存储以下链接 URL hostname i imgur com webid qkELz jpg 我想要在这两个字段上有一个唯一且稀疏的复合索引 因为 的组合hostname and webid应该是独一无二的 webid总是会被查
  • ggplot2:geom_ribbon,alpha 取决于每个 x 沿 y 轴的数据密度

    ggplot2 中有没有一种方法可以根据点的密度生成具有不同 alpha 的 geom ribbon 或其他基于区域的 geom 以下代码生成 50 个有噪声的正弦波 每个样本具有随机 x 值 我不想绘制每一个点 因为我可能需要一千次或更多
  • 获取单个 Windows 应用程序当前音量输出级别,如音频混合器中所示

    我正在尝试编写一个 C 代码 该代码从每个访问声音输出的 Windows 应用程序输出当前的音频输出级别 如音量混合器不断变化的绿色条所示 该程序将每 10 毫秒检查一次 并输出如下内容 Windows Media Player 30 Mo
  • 比较 PHP 中的多维数组

    如何在 php 中比较多维数组 有简单的方法吗 我知道的最简单的方法 a b 请注意 您还可以使用 它们之间的区别是 With 双等于 顺序很重要 a array 0 gt a 1 gt b b array 1 gt b 0 gt a va
  • c recv() 读取直到出现换行符

    我正在用 C 语言编写 IRC 机器人 但遇到了障碍 在我的主函数中 我创建了套接字并连接 所有这些快乐的事情 然后我有一个 几乎 无限循环来读取从服务器发回的内容 然后我将读取的内容传递给辅助函数 processLine char lin