【问题标题】:getline over a socket通过套接字获取线路
【发布时间】:2009-10-19 14:56:54
【问题描述】:

是否有一个 libc 函数可以做与 getline 相同的事情,但可以使用连接的套接字而不是 FILE * 流?

解决方法是在套接字上调用 fdopen。这样做时应该注意哪些事项。做/不做的理由是什么。

这样做的一个明显原因是调用 getline 和 co,但也许重写一些自定义 getline 是一个更好的主意?

【问题讨论】:

    标签: c sockets stdio


    【解决方案1】:

    当您在套接字上调用读取时,它可能会过早地返回零值。 例如。

     read(fd, buf, bufsize)
    

    如果 tcp 套接字的内核缓冲区已满,则可以返回小于 bufsize 的值。 在这种情况下,可能需要再次调用 read 函数,除非它返回零或否定结果。

    因此最好避免使用 stdio 函数。您需要为 read 函数创建包装器,以实现对 read 的迭代调用,以便可靠地获取 bufsize 字节。只有当无法从套接字读取更多字节时,它才应该返回零值,就好像正在从本地磁盘读取文件一样。

    您可以在 Randal Bryant 的书 Computer Systems: A Programmer's Perspective 中找到包装。

    源代码可在this 站点获得。查找以 rio_ 开头的函数。

    【讨论】:

      【解决方案2】:

      如果套接字连接到不受信任的输入,请为任意时间范围内的任意输入做好准备

      • \r\n 之前的\0 个字符
      • 永远等待 \r 或 \n 中的任何一个
      • 任何其他可能丑陋的东西

      解决任意时间和任意数据的一种方法是在读取时提供超时,例如通过 select(2) 并将您实际接收到的数据逐字节馈送到一些编写良好的状态机。

      【讨论】:

        【解决方案3】:

        问题是如果您没有收到新行(\n 或 \r\n,取决于您的实现)程序将挂起。我会编写您自己的版本,该版本还会调用 select() 以检查套接字是否仍可读/可写并且没有任何错误。真的没有办法判断是另一个“\n”还是“\r\n”,所以请确保您知道来自客户端/服务器的数据是一致的。

        假设您编写了一个使用 getline() 读取标题的网络服务器。如果攻击者简单发送

        GET / HTTP/1.1\r\n
        This line isn't terminated: bla
        

        getline 的调用将永远不会返回,程序将挂起。可能会消耗您的资源,最终可能会发生 DoS。

        【讨论】:

          猜你喜欢
          • 2015-02-12
          • 1970-01-01
          • 2015-01-19
          • 2014-08-27
          • 1970-01-01
          • 2016-07-24
          • 1970-01-01
          • 1970-01-01
          • 2012-12-28
          相关资源
          最近更新 更多