在漫长的软件开发的过程中,总会遇到这样或者那样的问题,问题的出现总是迥然的相似:开始会为难缠的bug而苦恼,而后会为找到一些蛛丝马迹而兴奋起来,随后当假象被推翻的时候,又会回到初始的状态……但好在最终的结果总是令人喜悦的!
最近就遇到一件棘手的事情,有一些实时数据需要用无线连接器(客户端Client)通过Socket与服务器建立连接,并将数据发送给服务器,之后断开连接。这个流程看似没有问题,实际上服务器和客户端之间也一直这么“友好”的合作着,可是因为机房的一次断电,出现了一件奇葩的事情:所有客户端只能跟服务器建立第一次“友好”的合作,两次以上二者之间就再也无法通信。
总结一下大致的问题:所有客户端的第一条数据发送成功,随后所有的客户端第二条数据全部发送失败。
猜测原因是客户端与服务器之间建立socket连接之后没有断开导致,于是通过netstat命令查看一下客户端与服务器之间实时通信情况:
netstat -ano | findstr “6800” (6800位服务器监听端口号)
netstat检测数据
可以看出,服务端检测出所有的tcp状态都是ESTABLISHED。
接下来看一下socket建立连接与断开连接的通信过程:
客户端与服务端通过3次握手建立连接
客户端与服务端通过4次挥手断开连接
通过以上两张图可以看出,客户端与服务端之间仅仅通过3次握手实现了连接,却没有断开,究其原因,是因为客户端建立第一次连接之后,没有跟服务端进行断开连接通信,直接断电关机(wify发射器为了节省电能,每五分钟定时启动一次,发送完数据直接断电)。也就是说客户端并未通知服务端断开连接,服务端采用的是被动关闭连接,断电之后直接发送第二条数据,导致通道被阻塞。
解决方案:
- 客户端建立通信后断开连接后再断电。
- 服务端采用主动关闭socket
又由于客户端是集成在硬件设备里,已经投入使用,所以最理想的方式就是采用方案二。至此,问题总算得以解决!