是否有一个 libc 函数可以做与 getline 相同的事情,但可以使用连接的套接字而不是 FILE * 流?
一种解决方法是在套接字上调用 fdopen。这样做时应该注意哪些事项。做/不做的理由是什么。
这样做的一个明显原因是调用 getline 和 co,但也许重写一些自定义 getline 是一个更好的主意?
当您在套接字上调用读取时,它可能会过早地返回零值。例如。
read(fd, buf, bufsize)
如果 tcp 套接字的内核缓冲区已满,则可以返回小于 bufsize 的值。在这种情况下,可能需要再次调用 read 函数,除非它返回零或否定结果。
因此最好避免使用 stdio 功能。您需要为 read 函数创建包装器,以实现对 read 的迭代调用,以便可靠地获取 bufsize 字节。仅当无法从套接字读取更多字节时,它才应返回零值,就好像正在从本地磁盘读取文件一样。
您可以在Randal Bryant所著的 Computer Systems: A Programmer's Perspective一书中找到包装器。
源代码可在此站点获得。查找以 rio_ 开头的函数。
如果套接字连接到不受信任的输入,请为任意时间范围内的任意输入做好准备
解决任意时序和任意数据的一种方法是在读取时提供超时,例如通过 select(2) 并将您实际接收到的数据逐字节馈送到一些编写良好的状态机。
问题是如果您没有收到新行(\n 或 \r\n,取决于您的实现)程序将挂起。我会编写您自己的版本,该版本还会调用 select() 以检查套接字是否仍然是可读/可写的并且没有任何错误。真的没有办法判断另一个“\n”或“\r\n”是否即将到来,因此请确保您知道来自客户端/服务器的数据将是一致的。
想象一下,您编写了一个使用 getline() 读取标头的 Web 服务器。如果攻击者简单发送
GET / HTTP/1.1\r\n
This line isn't terminated: bla
getline 的调用将永远不会返回,程序将挂起。可能会花费您的资源,最终可能会出现 DoS。