日期:2014-05-16  浏览次数:20664 次

一个关于socket长连接的问题
程序是用来和电信服务商进行长连接的,用的是电信的SMGP 3.0协议。
程序启动后,调用boost库的线程管理来启动一个线程函数SendData(string falg);
m_threadpool.schedule(boost::bind(&SMGPCT::SendData,this,"SMGPCTMT"));
在线程函数SendData(string falg)中,
做一个while(1)循环,里面先是调用ServerRecvTask()从中间件获取任务数据,
然后,若是没有数据,会进行30秒一次的链路测试ActiveTest(),问题就在这个链路测试中!
链路测试是先发送一个包给电信,然后等待电信的回执包,再由程序判断看回执包是否正确,
结果是如果隔的时间短的话,比如1-5秒之间,那么是收回的回执包是正确的,如果超过这个时间,比如之前设置的30秒,那么回执包怎么都不正确!
简单来说也就像下面这样:

SendData()
{
   while (1)
   {
      sleep(5); //正确的回执包
      //sleep(30);//错误的回执包
      ActiveTest();  
   }
}

ActiveTest()中的socket是用的Poco:Net中的StreamSocket

------解决方案--------------------
用sleep不合适吧,你应该是非阻塞socket+定时器来处理这个问题。sleep的话,sleep时间内,回执包没准就丢掉了。
------解决方案--------------------
有很多种方法的非阻塞,信号。但最简单的方法是用select非阻塞方式来实现,调用select时给定一个超时时间,在超时时间内如果收到数据你就读取,没收到就休眠。
------解决方案--------------------
首先你要知道数据在网路中存在是有时间限制的,如果你用sleep的话,那么就是阻塞状态,因为你说过:在没有数据的情况下,会进行30秒一次的链路测试ActiveTest(),那么在ActiveTest之前进行sleep的话,如果时间过长,就会出现数据丢失的状态,可以将ActiveTest放在sleep之前。