16.1 分离I/O流
2025/12/30大约 1 分钟
16.1 分离I/O流
分离I/O流的两种方法:
- 通过fork复制文件描述符,区分输入和输出使用的文件描述符;
- 通过以不同的方式调用fdopen,创建读模式FILE 和 写模式FILE。
分离后都能降低实现难度、提高性能
”流“分离带来的EOF问题
使用标准I/O函数时如何进行半关闭?
使用第一种分离I/O流的方法时,通过 shutdown(int sockfd, int how); 关闭输出流
- 能否通过fclose 关闭写模式FILE达到半关闭的目的?(仍可通过读模式FILE接收数据)
- 能否仍然使用
shutdown关闭输出流?
首先看以下使用fclose 关闭输出流的效果
实现:
//建立连接
FILE *readfp = fdopen(clnt_sock, "r");
FILE *writefp = fdopen(clnt_sock, "w");
fputs("Hello World!\n", writefp);
fputs("Welcome to server.\n", writefp);
fflush(writefp);
fclose(writefp);
fputs("closed writefp\n", stdout);
sleep(5);
fgets(message, sizeof(message), readfp);
fputs(message, stdout);
fclose(readfp);
close(serv_sock);效果:
PSH 和 FIN 基本是连着,也就是刚刚fflush,调用fclose就立即发送了FIN
12 为 PSH,ACK 13为 FIN,ACK增加sleep,观察
fclose(writefp);前后进程打开的文件
前:
Network 3211 ming 2u CHR 136,8 0t0 11 /dev/pts/8
Network 3211 ming 3u IPv4 31005 0t0 TCP *:10086 (LISTEN)
Network 3211 ming 4u IPv4 31006 0t0 TCP 192.168.56.101:10086->192.168.56.1:9442 (ESTABLISHED)后:
Network 3211 ming 2u CHR 136,8 0t0 11 /dev/pts/8
Network 3211 ming 3u IPv4 31005 0t0 TCP *:10086 (LISTEN)- fclose
相关信息
The fclose() function flushes the stream pointed to by stream (writing any buffered
output data using fflush(3)) and closes the under-lying file descriptor.
fclose会关闭底层的fd
相关信息
fclose(writefd) 完全终止了套接字,而不是半关闭
可以使用shutdown进行半关闭
shutdown(clnt_sock, SHUT_WR);
fgets(message, sizeof(message), readfp);
//...