getline over socket

是否有一个libc函数可以执行与getline相同的操作,但是可以使用连接的套接字而不是FILE *流吗?

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

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

当你在套接字上调用read时,它可以提前返回零值。 例如。

read(fd, buf, bufsize) 

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

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

你可以在Randal Bryant的“ 计算机系统:程序员的视角 ”一书中找到包装器。

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

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

想象一下,您编写了一个使用getline()读取标题的Web服务器。 如果攻击者简单发送

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

getline的调用永远不会返回,程序会挂起。 可能会花费您的资源,最终可能会出现DoS。

如果套接字连接到不可信输入,请准备在任意时间范围内进行任意输入

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

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