zoukankan      html  css  js  c++  java
  • 协议开发 中移动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到队//列中等待用户提取

    ………….

    }

     待续.....

     


  • 相关阅读:
    Netty之ProtoBuf(六)
    Netty对WebSocket的支持(五)
    Netty之心跳检测技术(四)
    Netty之多用户的聊天室(三)
    Docker Compose 笔记
    vue.js学习笔记
    powerdesigner 生成C#code 实体 模板设备
    .net 接收post 的参数 加载xml
    powerdesigner 生成实体代码 附加生成xml
    PostgreSql 获取所有的表、视图、字段、 主键
  • 原文地址:https://www.cnblogs.com/bobox/p/626010.html
Copyright © 2011-2022 走看看