协议开发 中移动CMPP2.0协议API(三)
協議開發 中移動CMPP2.0協議API(三)
?
云網(jimzj@21cn.com)
?
接上篇...
五、發送接口
對于API來說,最重要的一部分就是去做發送數據了。通過SOCKET套接字與網關相連接后,將自己的數據發送出去。
在發送數據前,組裝好要發送的數據包,將數據COPY一份到發送窗口,對于不要回應的數據包,只要發送成功,就可以退出發送進程。對于要等待回應的包,啟動一個時鐘來作為檢測是否收到了回應,并返回結果給發送窗口。設置發送的次數標志,如果發送第一次超時,按設定的發送次數,再發送。如果出現一次發送不成功,可以設置一個標志位,去發送一次鏈路檢測標志,如果鏈路檢測失敗,應該重新連接或者是在用戶發送時直接返回鏈路斷開的結果。
?
CMPP_PACKAGE * _pkg = ( CMPP_PACKAGE * )buf ;
??? int err = API_E_UNKNOW_ERR ;
??? if( _soc == INVALID_SOCKET ) return API_E_INVALT_SOC ;
??? while( _pkg->n > 0 )
??? {
??????? _pkg->n = _pkg->n - 1 ;?? //發送次數
??????? _lastacttime = time( NULL ) ;
?
??????? EnterCriticalSection( &_csec_soc ) ;
??????? try
??????? {
??????????? err = send( _soc, buf, len, 0 ) ;
??????? }
??????? catch( ... )
??????? {
??????? }
??????? LeaveCriticalSection( &_csec_soc ) ;
?
??????? if( err < len ) //發送不成功
??????? {
??????????? err = API_E_SO_SENDERR ;
??????????? continue ;
??????? }
?
??????? //不要回應結果的直接跳出
??????? if( _pkg->resp == false )
??????? {
??????????? err = 0 ;
??????????? break ;
??????? }
?
??????? //等待回應事件
??????? …………
??? }
??? //如果發送超時,設置發送鏈路檢測標志開
??? if( err == API_E_SO_OVETIME )
??? {
??????? _needacttest = _needacttest + 1 ;
??? }
?????? return err;
?
六、接收接口
??????? 對于數據的接收,因為發送短信的接口的數據量并不是很大,所以可以采用接收到
一部分,解釋一部分的功能,這樣的就可以減少設計上的難度,當然也可以一次接收緩沖中的數據,再一段段去分析,也不是很難。
??????? 對于接收,啟用一個新的線程,這樣也可以保證接收的及時性與可調度性。先接收包頭信息確定整個數據包的長度,直到接收到一個完整的包的內容才進行下一個包的接收,有些包也可能是沒有包體結構的,所以也可以在收到正確的包頭后就進行分析結構如下:
?
??????? //先接收包頭部分,以確定包的大小、類型
??????? err = _pscoket->_recv( _pscoket->_rec_window, sizeof( CMPP_HEAD )) ;
??????? if( err == SOCKET_ERROR || err == API_E_INVALT_SOC ) continue ;
?
??????? CMPP_PACKAGE * _recpkg = ( CMPP_PACKAGE * )_pscoket->_rec_window ;
??????? if( ntohl( _recpkg->head.size ) > 0 )
??????? {
??????????? //接收包體
??????????? _reclen = 0 ;?? //已接收長度
??????????? _recdatalen = ntohl( _recpkg->head.size ) - sizeof( _recpkg->head ) ;
??????????? do
??????????? {
??????????????? Sleep( 1 ) ;
??????????????? _recdatalen = _recdatalen - _reclen ;
??????? ??????? err = _pscoket->_recv( _recpkg->data + _reclen, _recdatalen );
??????????????? if( err == SOCKET_ERROR || err == API_E_INVALT_SOC ) continue ;
??????????????? _reclen = err ;
??????????? } while( _recdatalen - _reclen > 0 ) ;
??????????? if( _recdatalen > _reclen ) continue ;
??????? }
??????? try
??????? {
??????????? _pscoket->_analysisrecpack( _recpkg ) ;? //分析包的內容
??????? }
??????? catch( ... )
??????? {
??????? }
?
?
七、分析協議包
接收到CMPP的一個完整的協議包后,根據命令字去作分析,相對來說并不是一個很難的事情,不過要注意是就是要把網絡數據流轉化為主機數據流這個問題。
unsigned char _result = 0 ;
??? CMPP_DELIVER * _msg = ( CMPP_DELIVER * )_recpkg->data ;
??? DELIVER_CONTENT * _pcont = ( DELIVER_CONTENT *)_msg->msgcontent ;
?
??? if( _msg->msglen <= 0 )
??? {
??????? _result = 4 ; //接收到的長度前誤,要求網關服務器重發這個包
??? }
??? else if( _msg->msglen > 200 )
??? {
??????? _result = 6 ; //接收到的長度前誤,要求網關服務器重發這個包
??? }
??? else if( _msg->delivery != 0 || _msg->delivery != ?1 )
??? {
??????? _result = 1 ; //接收到的協議格式有誤,要求網關服務器重發這個包
??? }
?
??? //接收到錯誤的信息直接返回
??? if( _result > 0 )
??? {
??????? _deliverresp( _recpkg->head.seqid, _msg->msgid, _result ) ;
??????? return ;
??? }
??????????????
??????? if( _fCltGetDeliver )
{
//如果客戶端程序采用的是回調函數來取得接收到的短信或狀態,調用回
//調函數傳遞數據
……………
}
else
{
//如果客戶端采用的是自已從隊列中提取的方式,把數據直接PUSH到隊//列中等待用戶提取
………….
}
?待續.....
?
作者Blog:http://blog.csdn.net/jimzj/
轉載于:https://www.cnblogs.com/bobox/archive/2007/01/21/626010.html
總結
以上是生活随笔為你收集整理的协议开发 中移动CMPP2.0协议API(三)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: style
- 下一篇: GIS开发随笔(3)——ArcXML和N