4

It's often said that one shouldn't use C standard I/O functions (like fprintf(), fscanf()) when working with sockets.

I can't understand why. I think if the reason was just in their buffered nature, one could just flush the output buffer each time he outputs, right?

Why everyone uses UNIX I/O functions instead? Are there any situations when the use of standard C functions is appropriate and correct?

4

4 回答 4

8

您当然可以使用stdio套接字。你甚至可以编写一个只使用stdinand的程序,stdoutinetd(它提供一个 onSTDIN_FILENO和的套接字STDOUT_FILENO)运行它,即使它根本不包含任何套接字代码,它也能工作。

您不能做的是将缓冲 I/O 与selector混合,poll因为没有fselectfpoll正在处理FILE *'s,您甚至无法自己实现一个,因为没有标准的方法来查询 aFILE *以确定其输入缓冲区是否为空。

只要您需要处理多个连接,stdio就不够好。

于 2012-08-19T20:35:50.803 回答
3

当你有一个简单的场景,一个套接字处于阻塞模式并且你的应用程序协议是基于文本的时,这完全没问题。

如果使用多个或非阻塞套接字、任何类型的二进制编码以及任何实际性能要求,它很快就会变成一个巨大的痛苦。

于 2012-08-19T20:57:08.480 回答
2

不知道有什么直接的反对意见。这很可能会正常工作。

同时我可以想象一个平台,在哪里fprintf()并且fscanf()有自己的缓冲区,停留在文件描述符层之上。您可能无法刷新这些缓冲区。

很难谈论所有可能的平台。这意味着最好使用套接字来避免这种情况。

在一天结束时,应用程序应该解决应用程序问题。它不应该是编译器/库测试。

于 2012-08-19T20:35:01.210 回答
0

这是因为套接字(例如 TCP 套接字)是可读写的,就好像它们是文件或管道一样,但这只是一种抽象。网络连接的内部工作比本地文件或管道复杂得多。

首先,读取文件总是“快速”的,无论是获取数据还是碰到文件结尾。另一方面,如果您期望来自 TCP 连接的 500 个字节并且它发送 499(并且连接没有关闭),您可能会永远等待。写入也是同样的事情:它会在 TCP 输出缓冲区之后阻塞。

即使是最基本的程序也需要处理超时、断开连接以及所有这些与 FILE 自己的缓冲 I/O 交互的事情,即使是教科书示例也不能很好地工作。

于 2013-12-13T13:43:05.397 回答