前面我们解决了并发服务端的问题, 但是还是没有解决掉客服端的bug.
问题重现
我们以上一节的代码为例浮现这个bug.
完整代码 : fork_SIGCHLD.c
可能你已经忘了客服端的问题了, 这里在重新说明一下 : 当建立连接后, 服务端主动关闭后, 客服端并没有立即退出, 而是处于阻塞状态直到有输入才会退出.
问题分析
分析问题的时, 应该先来看一下抓包的情况.
问题基本也能分析出来.
- 服务端关闭时向客服端发送
FIN
, 根据四次挥手的原则, 此时客服端还能够向服务端发送数据, 也就解释了客服端没有发送FIN
而是阻塞在read
函数等待输入数据, 但服务端其实发送FIN
后就被关闭了, 等待客服端发送数据后因为对端已经完全关闭了所以发送RST
. - 客服进程看不到
RST
, 因为在调用read
之后立即调用write
并且收到服务端的FIN
后返回0, 进程继续阻塞在第二次的read
函数.