getline over socket

时间:2009-10-19 14:56:54

标签: c sockets stdio

是否存在与getline完全相同的libc函数,但是可以使用连接的套接字而不是FILE *流吗?

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

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

3 个答案:

答案 0 :(得分:4)

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

 read(fd, buf, bufsize)
如果tcp套接字的内核缓冲区已满,

可以返回小于bufsize的值。 在这种情况下,可能需要再次调用读取函数,除非它返回零或负结果。

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

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

源代码位于this网站。寻找以rio _开头的函数。

答案 1 :(得分:3)

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

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

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

答案 2 :(得分:2)

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

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

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

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