【问题标题】:gawk to read last bit of binary data over a pipe without timeout?gawk 在没有超时的情况下通过管道读取二进制数据的最后一位?
【发布时间】:2012-04-06 08:25:44
【问题描述】:

我有一个已经用 gawk 编写的程序,它可以从互联网上下载大量的小信息。 (媒体扫描仪和索引器)

目前它启动 wget 来获取信息。这很好,但我想简单地重用调用之间的连接。程序的运行可能会对同一个 api 服务进行 200-2000 次调用。

我刚刚发现gawk可以做网络,发现geturl 然而,该页面底部的建议很受重视,我找不到一种简单的方法来阅读最后一行并保持连接打开。

由于我主要读取 JSON 数据,我可以设置 RS="}" 并在正文长度达到预期的内容长度时退出。不过,这可能会与任何尾随空格中断。我想要一个更强大的方法。有没有人有更好的方法来实现在 awk 中保持连接打开的零星 http 请求。目前我有以下结构...

con="/inet/tcp/0/host/80";

send_http_request(con);

RS="\r\n";

read_headers();

# now read the body - but do not close the connection...
RS="}"; # for JSON
while ( con |& getline bytes ) {
    body = body bytes RS;
    if (length(body) >= content_length) break;
    print length(body);
}
# Do not close con here - keep open

很遗憾,这件小事似乎破坏了这里的所有潜力。万一有人问:) ..

  • 最初选择 awk 是出于历史原因 - 当时这个嵌入式平台上没有很多其他语言选项。
  • 提前收集所有 URL 并传递给 wget 并不容易。
  • 在 perl/python 等中重新实现并不是一个快速的解决方案。
  • 我已经研究过尝试将 url 传送到命名管道并导入 wget -i - ,但这是行不通的。数据被缓冲,并且 unbuffer 不可用 - 我认为 wget 在处理之前收集所有 URL,直到 EOF。
  • 数据很小,所以压缩不足不是问题。

【问题讨论】:

  • 只替换 wget 部分是否公平?我不得不认为,为 wget 编写一个替代品,它可以从标准输入中读取 URL,并将数据写入标准输出,这比尝试将功能构建到 gawk 脚本中要容易得多。
  • 虽然这不能回答您的问题,但您可能会发现此讨论具有一定的价值:groups.google.com/forum/#!topic/comp.lang.awk/RinvdXVq11o。还有其他讨论,搜索 wget 和 inet/tcp 。祝你好运,如果你想通了,请发表你的答案!
  • 只是一个快速更新,我实现了一个 hackish 版本,它会检查主机、内容类型和内容编码来决定要使用的最佳分隔符。它可以重用连接,但是在这个特定的嵌入式系统(NMT)上,重用连接的所有性能增益都被它读取正文的速度(或者可能是一般的 IO / 字符串速度)所损失。产生额外的 wget 进程并没有真正的收获。
  • @sarnold - 我可能会在某个时候这样做。我花在这上面的时间比我应该没有的时间要多——但我了解了 gawk 网络以及如何处理分块编码:)
  • @shelter - 谢谢 - 这听起来像是使用正确的工具完成正确的工作。羞耻对 wget 的一个“小”代码更改将非常有用。

标签: http awk wget gawk


【解决方案1】:

连接重用的问题来自 HTTP 1.0 标准,而不是 gawk。要重用连接,您必须use HTTP 1.1 or try some other non-standard solutions for HTTP 1.0。不要忘记在您的 HTTP/1.1 请求中添加 Host: 标头,因为它是强制性的。

您在阅读响应正文时缺乏稳健性是对的。对于面向线路的协议,这不是问题。此外,即使使用 HTTP 1.1,如果您的脚本在不应该等待更多数据时锁定等待更多数据,服务器将再次由于不活动而关闭连接。

作为最后的手段,你可以用你喜欢的任何语言编写自己的 HTTP 检索器,它可以重用连接(我假设都是到同一个远程主机),还可以为你插入一个特殊的记录分隔符。然后,你可以控制它from the awk script

【讨论】:

  • 感谢您的回复,我正在使用 HTTP 1.1 ok,并且重新连接在 awk 中处理得非常好。就是这样,正如您所指出的,除非我读取响应正文的最后一个字节,否则连接可能不会被重用,如果我尝试读取太多,那么它将阻止等待来自服务器的更多输入。
猜你喜欢
  • 2011-01-22
  • 2012-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-05
  • 1970-01-01
  • 2021-12-15
相关资源
最近更新 更多