分离I/O流
上一章中使用文件描述符的套接字没有办法半关闭,即没有办法关闭自己的发送端,而仍可接收对方的消息。因为读写两个模式的FILE指针都是基于同一个文件描述符创建的。
# gcc sep_serv.c -o sep_serv
# ./sep_serv 9190
Connected client.
# gcc sep_clnt.c -o sep_clnt
# ./sep_clnt 127.0.0.1 9190
Connected
FROM SERVER: Hi!
FROM SERVER: Nice to meet you.
但我们可以在创建FILE指针前先复制文件描述符,销毁所有文件描述符才能销毁套接字。
文件描述符的复制和半关闭
#include <unistd.h>
/*
* @params
* fildes: 需要复制的文件描述符
* fildes2: 明确指定的文件描述符整数值
*/
int dup(int fildes); // 成功时返回复制的文件描述符,失败时返回-1
int dup2(int fildes, int fildes2);
验证这两个函数的功能:
# gcc dup.c -o dup
# ./dup
fd1=3, fd2=7
Hi~
It's a nice day~
Hi~
修改服务器端使其可以进入半关闭状态:
# gcc sep_serv2.c -o sep_serv2
# ./sep_serv2 9190
Connected client.
FROM CLIENT: Thank you!
# ./sep_clnt 127.0.0.1 9190
Connected
FROM SERVER: Hi!
FROM SERVER: Nice to meet you.
习题
- 下列关于FILE结构体指针和文件描述符的说法错误的是?
a. 与FILE结构体指针相同,文件描述符也分输入描述符和输出描述符
b. 复制文件描述符时将生成相同值的描述符,可以通过这2个描述符进行I/O
c. 可以利用创建套接字时返回的文件描述符进行I/O ,也可以不通过文件描述符,直接通过FILE结构体指针完成
d. 可以从文件描述符生成FILE结构体指针,而且可以利用这种FILE结构体指针进行套接字I/O
e. 若文件描述符为读模式,则基于该描述符生成的FILE结构体指针同样是读模式;若文件描述符为写模式,则基于该描述符生成的FILE结构体指针同样是写模式
abe。- EOF的发送相关描述中错误的是?
a. 终止文件描述符时发送EOF
b. 即使未完全终止文件描述符,关闭输出流时也会发送EOF
c. 如果复制文件描述符,则包括复制的文件描述符在内,所有文件描述符都终止时才会发送EOF
d. 即使复制文件描述符,也可以通过调用shutdown函数进入半关闭状态并发送EOF
abc。
附录
[1] Github