我应该使用文件描述符还是流来读写套接字?

11

在套接字设置完成后,是更好的实践方法使用read(2)和write(2)调用套接字描述符,还是使用fdopen(3)将流与套接字描述符相关联,然后使用stdio(3)函数?

int sfd = socket(PF_INET, SOCK_STREAM, 0);
// setup the socket using sfd
FILE * stream = fdopen(sfd, "r+");
// use fprintf, fscanf, etc

编辑:我还取消了流的缓冲

setbuf(stream, NULL)
为了避免像评论中提到的那样必须刷新它。
我一直在使用这种方法,因为它让我重用为FILE*流编写的代码,并且我有使用格式字符串的优势(我正在处理人类可读的文本)。GNU似乎在暗示这是一个好主意。 然而,通常当我看到使用套接字的代码时,套接字描述符被用于所有操作,而不是流。使用低级别函数是否有优势? http://www.gnu.org/software/libc/manual/html_node/Streams-and-File-Descriptors.html

3
请记住,C文件流默认是有缓冲的,所以当发送时您需要手动清除缓冲区。即使您将套接字设置为非阻塞模式,读取操作仍有可能被阻塞。 - Some programmer dude
如果您使用包装的I/O的性能足够好,并且它使代码简单化,那么请继续使用它。 - paddy
1
在我看来,read() 和 write() 使得处理错误条件更加直接,因为它们不会掩盖任何错误。 - thuovila
在我看来,使用C文件流与套接字是麻烦的好方法。 - Maxim Egorushkin
1个回答

5
如果您需要更精确地控制和处理错误条件,请使用readwrite。如果您不需要,且更喜欢使用stdio函数的便捷性,则请使用FILE*包装器。
使用FILE *包装器的一个问题是您无法控制数据何时以及如何被写入套接字。如果不小心,这可能导致网络利用效率低下和过多的延迟(由于 Nagle算法与延迟确认交互而导致)。
如果这是一个高性能的Internet应用程序,建议直接使用readwrite

通过使用 recvsend,可以实现更精确的控制,因为它们允许指定标志,例如 MSG_NOSIGNAL - Maxim Egorushkin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接