【问题标题】:Download a file from the web in C++ without using non-standard libraries on Linux在不使用 Linux 上的非标准库的情况下,使用 C++ 从 Web 下载文件
【发布时间】:2010-11-04 13:49:24
【问题描述】:

当我说非标准库时,我指的是像 Boost、libCurl 和任何其他可能比标准 C++ 更容易做到这一点的东西。原因是我正在编写一个应用程序作为课程作业(该课程专用于 C++),并且我只需要使用标准库和函数。

我希望使用用户提供的 URL 下载 RSS 文件(我正在构建一个基本的 RSS 客户端),我面临的最大问题是我不确定如何获取归档。一旦我克服了这一点,解析它以获取 xml 标签并显示内容将相对简单。我一直在环顾四周,只找到了使用非标准库的解决方案,通常是 libCurl。如果有人可以快速提醒我应该注意什么,我将不胜感激。

另外,如果你认为你在帮助我作弊,那你不是。任务是构建我们选择的应用程序,并且我们正在根据我们对语言各种功能的使用进行评分(它必须包含如此多的类,使用这些变量类型等)。

【问题讨论】:

  • 真正的问题是什么?您是否希望有人为您编写一个应用程序来执行此操作?您是否自己编写过并且遇到过问题?
  • @jon hanson 我只是在找人指出我正确的方向,我已经更新了问题以反映这一点。
  • “一旦我克服了这一点,解析它以获取 xml 标签并显示内容将相对简单。” - 祝你好运。
  • 注意相对这个词的使用;)

标签: c++ linux url


【解决方案1】:

查看Beej's Guide to Network Programming 以快速但出色地介绍套接字。如果您不能使用任何非标准库,您唯一的选择是手动连接端口 80 并自己发出请求。

假设即使是 C++ 的初级知识,这也应该是您所需要的。

【讨论】:

    【解决方案2】:

    首先,仅使用标准 C++ 无法完成。标准 C++ 或标准 C 中都没有网络接口。

    如果您需要采用“自己动手”的方法,那么您的意图可能是使用您平台的套接字 API。对于 linux,这是 POSIX 标准的一部分,而不是 C++,可从<sys/socket.h> 获得。

    基本流程是:解析URL;查找域的IP地址;创建一个套接字;连接插座;向套接字写入 HTTP 请求;从套接字读回 HTTP 响应;清理干净。

    显然,HTTP 库要方便得多,尤其是因为 HTTP 下载可能比我上面描述的更复杂(例如,如果服务器响应重定向)。几乎所有的 linux 发行版都会提供libcurl,和/或curlwget 程序。

    【讨论】:

    • +1 指出标准 C++(或 C)库中没有网络接口。
    【解决方案3】:

    编写一个程序来建立一个套接字连接是比较简单的。

    http://www.linuxhowtos.org/C_C++/socket.htm

    现在您已经有一个向 HTTP 服务器打开的套接字,您需要了解如何请求文档以及如何解码回复:

    http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html

    基本上你需要发送:

    GET<SP><URL><SP>HTTP/1.1<CRLF>
    
    Where:
      SP:    Single Space
      CRLF:  \r\n
      URL:   The Full URL of the page including the server name.
    

    你得到的将是

    http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6

    HTTP/1.1<SP>200<SP>OK<CRLF>
    (<Header><CRLF>)*
    <CRLF>
    <Document>
    

    以上意思是:

    • 第一行是应包含 200 OK 的响应行。
      • 如果没有,则存在某种错误,您应该放弃。
    • 后跟 0 个或多个标题行
      • 忽略这些行
    • 将有 1 个空行来标记标题的结尾。
    • 然后文档将在流中。

    【讨论】:

    • "如果没有,那就是有某种错误,你应该放弃。" - 嗯,有 3xx。对于用户提供的 URL,很可能需要跟踪重定向。
    【解决方案4】:

    如果你真的想在不使用 libcurl 的情况下这样做,你可以随时打开一个 tcp 套接字然后发送:

    GET /myurl 
    

    (http 1.0 或者最好使用http 1.1)

    基本上,您正在编写一个非常简单的 http 协议客户端实现。

    【讨论】:

    • libcurl 绝对属于“标准库”类别。
    • @hassan 我同意,但这个问题专门要求“不使用 libcurl”,这几乎没有选择
    • 确实,刚刚看到了。奇怪的是,任何大学讲师都会带领他的班级假设 libcurl 被认为是非标准的。无论如何,OP 的下一个最佳答案是“阅读”curl 源代码。
    • 对于简单的 http 请求,libcurl 源代码并不是特别清楚,我怀疑这个作业的“学习成果”类似于“深入了解 http 协议”之类的东西。 RFC2616 或维基百科似乎比阅读真正的实现更适合。
    【解决方案5】:

    您可以下载wget标准实用程序的源代码

    【讨论】:

      【解决方案6】:

      由于不允许使用非标准库,您可以为 linux“curl”命令编写自己的原始包装类(我假设您使用的是 linux)。 curl 是一个非常强大的命令,它可能会做你需要做的事情。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-08-12
        • 2020-12-08
        • 1970-01-01
        • 2014-10-21
        • 2023-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多