MFC的CSocket重连
MFC的坑是真的多……上个时代的大佬都是怎么过来的。
References:
先介绍下场景,两台机器通过socket通信,一台服务端,一台客户端。现客户端要加上自动重连功能,在服务端重启后能自己连上来。
虽然也找了很久,但是无奈关于CSocket的资料太少了,大家无非几个思路:
- 通过心跳主动检测服务器是否正常工作
- 通过recv方法读缓冲区
- 调用getsocketopt函数检测
- 调用select函数。
由于recv方法读取的是缓冲区,所有检测的实时性不高。getsocketopt经过测试,只能检测到刚开始的连接失败状态,一但连接成功后再次断开,此方法就不能检测了。其他的也懒得去采坑了。最后想到了直接发送一个消息给服务端,Send函数如果成功发送则返回发送消息的长度,否则返回-1,虽然可能有其他原因导致发送失败,不过和网络比起来可以忽略了。
可以判断是否连接之后就是重连了,如果连接断开要定时重连。由于程序中本来就有网络检测的线程,就直接在线程中进行重连了,于是坑来了。每次关闭socket的时候程序都崩溃,但是单独写的demo中就能正常运行。终于发现原来MFC的CSocket封装了线程状态,在创建socket的时候也会记录当前线程的信息。这就意味着创建和关闭只能在同一个线程。
socket需要在程序启动时就连接,所以不可能放在网络检测线程中启动,还是要主线程来初始化,那么就必须由主线程重连了,最后使用了MFC的计时器Timer在主线程完成重连的工作。