chapter 5
1 TCP客户/服务器程序示例
服务器程序main函数:
服务器str_echo函数
客户端main函数
客户端str_cli函数
2 正常启动
3 正常终止
4 信号处理
5 处理SIGCHLD信号
6 wait/waitpid
7 异常讨论
1)accept返回前连接终止
除了系统中断(accept被返回,只需重新accept),当完成三路握手后客户TCP发送一个RST复位也会导致accept返回一个非致命的错误。
图片
但是如何处理第2种,却取决于不同的系统实现:
Berkeley完全在内核处理终止的连接,服务器进程看不到。
SVR4返回EPROTO错误(协议错误)
POSIX返回ECONNABORTED错误,这个错误更明显,方便服务器定位。
2)服务器进程终止
启动客户服务器对,然后杀死服务器子进程。
1 服务器子进程所有打开的文件描述符关闭,并向客户发送FIN,客户TCP相应一个ACK(但此时客户进程阻塞在fets调用上,等待终端接收文本)
2 SIGCHLD信号发动给服务器父进程,并得到处理。
3 客户进程接收输入,发送给服务器进程,服务器TCP因为已经关闭先前子进程,响应RST,但是客户进程看不到这个RST,会接收到先前因为阻塞而未处理的FIN,然后出错退出。
这里因为客户有2个输入源:套接字和用户输入,不能单纯阻塞在其中一个。
3)SIGPIPE信号
当一个进程向某个已收到RST的套接字执行写操作时,内核向该进程发送SIGPIPE信号。该信号的默认行为是终止进程。如果不愿意终止进程要捕获该信号。不管是捕获该信号还是忽略该信号,写操作都返回EPIPE错误。
4)服务器主机崩溃
服务器主机崩溃后,已连接网络上发不出任何东西。
客户发送数据由writen写入内核,再由客户TCP作为一个数据分节发送,客户阻塞在read调用上。