前面我们虽然解决了困惑我们很久客服端的问题, 但是虽然解决了但是该客服端还有更加大的隐患存在, 接下来我们就来看一下问题所在和问题解决办法.
问题浮现
使用前面IO复用之select 的客服端和服务端都改写成的完整代码做实验.
完整代码 : select_server_client.c
服务端运行:
./a.out 1 8080 127.0.0.1
客服端运行:
./a.out 2 8080 127.0.0.1 < select_service_client.c
客服端输入一段代码进行回显即可, 实验结果如下:
可以看到, 客服端并没有完整的接收到所有的数据就关闭了, 难道丢失数据了? 服务端为什么也关闭?
怎么回事, 怎么越改越错, 完全不如之前的IO分离了. 不急不急, 找到bug问题所在就容易解决了.
问题分析
通过抓包我们来分析, 抓包结果如下 :
可以看到服务端很认真的将数据发送给客服端, 但是客服端发送完数据之后就直接关闭了, 而服务端并没有完整的将数据发送完; 当客服端关闭后服务端再发送数据就收到RET
. 所以后面服务端的数据就丢失了, 客服端并没有收到所有的数据.
问题所在就是客服端关闭的太早了, 并没有正常的四次挥手就关闭了. 看来客服端不能直接close
关闭套接字, 而是应该等待把服务端发送过来的所有数据全部接收完了后调用 close
才行, 但是 close
没有办法判断什么时候读完啊.
接下来介绍shutdown
函数来解决