封装了P2P连接与数据传送过程的DLL正式版-PPQ.DLL v1.0(三)

类别:VC语言 点击:0 评论:0 推荐:


十四 PTask类中的函数说明

* 函数名称:
*   EndThread()
*
* 参数:
*   BYTE        bySuffix        -对线程组中的哪一个线程进行操作的标识。
                当取值为0和最大线程个数之间的值时,表示终止指定的线程。
                当取值为OPER_FIRST_ELEMENT时,表示终止线程组中第一个正在运行的线程。
                当取值为OPER_LAST_ELEMENT时,表示终止线程组中的最后一个正在运行的线程。
                当取值为OPER_ALL_ELEMENT时,表示终止线程组中所有正在运行的线程。

                关于OPER_FIRST_ELEMENT,OPER_LAST_ELEMENT,OPER_ALL_ELEMENT的定义,请查阅PDefine.h文件在枚举中定义的以 OPER_ 打头的常量。
*
* 返回值:
*   无
*
* 说明:
*    终止线程组中的一个线程。这是一个可以安全调用的函数,如果线程组中的线程不存在,函数不会进行任何操作。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   GetCompletedSize()
*
* 参数:
*   无
*
* 返回值:
*   DWORD                       -返回已经下载或传送的文件的总的尺寸。
*
* 说明:
*    该函数返回当前下载或传送任务已经完成的总的尺寸。

    注意:  只有当第一个下载或传送线程启动后,该值才有效。函数并不检测在PTask对象中规定的线程类型,因此,如果线程类型不是接收或传送类型,返回的值无实际意义。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   GetCurrentRunningThreadNo()
*
* 参数:
*   无
*
* 返回值:
*   BYTE                        -返回当前线程组中已经启动的线程的个数。
*
* 说明:
*   得到当前已经启动的线程的个数。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   GetPrivateAttribute()
*
* 说明:
*    该函数是DLL内部调用的函数,可以返回指定的私有属性的值,其参数在每次DLL启动时都不相同,因此,不要在外部去试图通过该函数去访问私有属性。

*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   GetThreadIDInArray()
*
* 参数:
*   BYTE        bySuffix           -线程在线程组中的下标号。取值范围在0和当前线程组的最大线程个数之间。
*
* 返回值:
*   LPPTHREADID                 -指定线程的PTHREADID结构的指针。
*
* 说明:
*    该函数返回线程组中指定线程的PTHREADID结构的指针。
     该函数是一个可以安全调用的函数,如果线程组中指定的线程不存在,则返回NULL。

    注意:  PTHREADID结构中的属性将影响线程的运行状态,不要去偿试修改这些值。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   GetTaskType()
*
* 参数:
*   无
*
* 返回值:
*   BYTE                        -任务类型的标识。
*
* 说明:
*    该函数将返回PTask对象中的任务的类型标识。一个PTask对象可以表示一组线程,这一组线程共同完成同一个任务。
   
    关于任务类型的标识请查阅PDefine.h文件在枚举中定义的以 TASK_ 打头的常量。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   InitValue()
*
* 参数:
*   无
*
* 返回值:
*   bool                        -是否初始化成功。
*
* 说明:
*    该函数初始化PTask对象中所有的值,使PTask对象可以重用。
   
     注意:  该函数会检测线程组中的线程是否已全部终止,如果线程组的线程已全部终止,则函数对PTask对象进行初始化,使其可以重用,并返回true。否则,函数不进行任何操作,返回false。这时PTask对象仍然保持原有的状态。

            关于该函数在何时使用,请查阅PDefine.h文件中的消息说明。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   IsTaskCompleted()
*
* 参数:
*   无
*
* 返回值:
*   DWORD                       -表明PTask对象的任务的完成状态。0表示任务已全部完成。非0值表示当前任务完成的状态。
*
* 说明:
*    该函数检测PTask对象的任务是否已全部完成,并返回当前的完成状态,表明当前任务已经进行到了哪一步。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   ResumeThread()
*
* 参数:
*   BYTE        bySuffix        -对线程组中的哪一个线程进行操作的标识。
                当取值为0和最大线程个数之间的值时,表示使指定的线程重新运行。
                当取值为OPER_FIRST_ELEMENT时,表示使线程组中第一个被挂起的线程恢复运行。
                当取值为OPER_LAST_ELEMENT时,表示使线程组中的最后一个被挂起的线程恢复运行。
                当取值为OPER_ALL_ELEMENT时,表示使线程组中所有被挂起的线程恢复运行。

                关于OPER_FIRST_ELEMENT,OPER_LAST_ELEMENT,OPER_ALL_ELEMENT的定义,请查阅PDefine.h文件在枚举中定义的以 OPER_ 打头的常量。
*
* 返回值:
*   DWORD                       -如果线程被恢复运行或该线程不存在,则返回0xFFFFFFFF。如果线程原先已经处于运行状态,返回线程处于运行状态的计数器,不作任何操作,线程继续处于运行状态。
*
* 说明:
*    使挂起的线程重新运行。这是一个可以安全调用的函数。
   
     注意:  如果参数为OPER_ALL_ELEMENT,返回值始终为0xFFFFFFFF。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   SafeRelease()
*
* 类型:
*   静态函数。
*
* 参数:
*   无
*
* 返回值:
*   无
*
* 说明:
*    调用该函数将安全地删除这个PTask对象。

     注意:  在删除一个PTask对象时,应该始终调用这个方法来删除对象。
           
                 在调用该函数前,应该将PTask对象从外部保存的列表中清除,一旦调用该函数,这个PTask对象将不可以再利用。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   SetMaxThreadNo()
*
* 参数:
*   BYTE        byNo            -想设定的最大线程的个数。取值范围0..10
*
* 返回值:
*   BYTE                            -当前线程组被设定的最大线程个数。
*
* 说明:
*    该函数用来设定线程组被允许启动的最大线程的个数。
   
     注意:  如果线程组中已经有线程处于运行状态,则该函数不作任何操作,只是简单地返回原先设定的最大线程个数。

            在线程组中没有线程被启动时,该方法会改变最大线程个数为指定的线程个数。

            当参数的值等于GET_MAX_THREAD_NO时,该函数返回原先设定的最大线程个数。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   StartTask()
*
* 参数:
*   BYTE       byType                  -任务的类型
*   DWORD  dwReTryCount=0   -当连接发生错误时的重试次数。0表示无限次重试。
*
* 返回值:
*   无
*
* 说明:
*   该函数将开始与pFriend属性中的好友对象去建立连接,然后执行byType参数规定的任务。

    特别注意:  当线程的类型为TASK_TCP_RECV、TASK_TCP_SEND、TASK_HTTP_RECV时,DLL的外部应该在创建PTask对象时,保存该对象的指针,以便将来查找。

                但是当类型为其它类型时,不要保存PTask对象的指针,因为DLL在连接被建立或超时后,会delete这个PTask对象。

                删除一个PTask对象时,应该调用PTask对象的SafeRelease()来删除这个对象,以释放资源,不要使用delete来直接删除该对象。

            关于连接被建立或超时后发出的消息,请查阅PDefine.h文件中的消息说明。

    现在可以选择的连接类型包括以下几种:
    TASK_TCP_SEND       -表明任务的类型为传送指定文件,自动采用多线程传送。

    TASK_TCP_RECV       -表明任务的类型为接收指定文件,自动采用多线程接收。

    TASK_HTTP_RECV     -表明任务的类型为从指定服务器上通过HTTP方式下载文件。 会根据服务器端是否支持断点续传来决定是否采用多线程方式下载。

    TASK_TCP_CHAT       -表明任务的类型为TCP聊天连接,可以实现语音传输。

    TASK_TCP                  -表明连接的双方都在采用这个DLL来接收指令对象,当双方建立连接并通过了身份验证后,会将已经建立好TCP连接的SOCKET句柄提交给DLL外部去处理,DLL不再记录和处理与该SOCKET相关的任何消息。这个SOCKET连接仍然可以通过调用PDefine中定义的静态方法来实现指令对象的传送和接收。

    TASK_TCP_USER        -表明连接的另一方没有采用这个DLL,它不能够解析指令对象,因为这个类型的连接只是建立了一个标准的TCP连接,双方都没有传递和接收过任何的消息。该连接被建立后,会将SOCKET句柄提交给DLL外部去处理,DLL不再记录和处理与该SOCKET相关的任何消息。你不应该使用这个SOCKET去传送指令对象,因为对方可能无法正确地解析你传递的数据流。

    对后续版本的支持:  以上的所有连接方式都会根据你本身是否处在防火墙内,而进行相关的处理,不管被连接方是否处在防火墙内,都能正确地与对方建立连接。

       关于突破防火墙建立连接,在现在的版本中还未实现。因为最近在忙于编写一个图象合成的软件,因此这方面的程序还未来得及编写,在后续的版本中将实现该功能。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   SuspendThread()
*
* 参数:
*   BYTE        bySuffix       -对线程组中的哪一个线程进行操作的标识。
                当取值为0和最大线程个数之间的值时,表示使指定的线程挂起。
                当取值为OPER_FIRST_ELEMENT时,表示使线程组中第一个正在运行线程挂起。
                当取值为OPER_LAST_ELEMENT时,表示使线程组中的最后一个正在运行的线程挂起。
                当取值为OPER_ALL_ELEMENT时,表示使线程组中所有正在运行的线程挂起。

                关于OPER_FIRST_ELEMENT,OPER_LAST_ELEMENT,OPER_ALL_ELEMENT的定义,请查阅PDefine.h文件在枚举中定义的以 OPER_ 打头的常量。
*
* 返回值:
*   DWORD                       -如果线程被挂起或该线程不存在,则返回0xFFFFFFFF。如果线程原先已经被挂起,返回线程被挂起的计数器,不作任何操作,线程继续处于挂起状态。
*
* 说明:
*    使线程挂起,这是一个可以安全调用的函数。
   
     注意:  如果参数为OPER_ALL_ELEMENT,返回值始终为0xFFFFFFFF。

 

十五 PTask类中的属性说明

* 属性定义:
*   bool        m_bIsSendMsg
*
* 类型:
*   这个属性在消息的响应函数中被赋值。缺省值为true。
*
* 说明:
*    当这个属性的值为true时,线程在每接收或传送了一定量的数据后,就会向DLL外部发送OMSG_SEND_DATA和OMSG_RECV_DATA消息。但每次发送了消息后,该值都会被设定为false,因此,如果你希望去响应这个两消息,你需要在这两个消息的响应函数中设定PTask对象中的该属性的值为true。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 属性定义:
*       DWORD           m_dwFileID
*
* 类型:
*    缺省值为0。
*
* 说明:
*    表示想接收或传送的文件的数字标识。
     如果类型为RECV_TYPE或SEND_TYPE,必需设定该属性的值为一个正确的数字标识。

    对后续版本的支持:  使用数字标识,而不是使用文件名来表示一个文件,主要是为了安全性和将来的扩展性。在后续的版本中,将提供方法来实现如何将真实的文件名保存为数字标识,并会实现如何为一个数字标识设定访问权限。

       关于如何实现数字标识的问题,请查阅PDefine.h文件中的回调函数说明。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 属性定义:
*   DWORD           m_dwIdentify   
*
* 类型:
*    这个属性必需在创建一个PTask对象时就赋与。
*
* 说明:
*    一个表明该对象的身份标识,是DLL向外部发送消息时传递的一个标识,你通过这个标识应该可以正确的查找到PTask对象。

   通常的作法是在DLL外部使用一个列表来保存类型为TASK_TCP_RECV、TASK_HTTP_RECV和TASK_TCP_SEND这些需要启动线程组的PTask对象的指针,这个属性的值中实际保存的是指向该PTask对象的指针。当接收到消息时,首先在列表中检查该指针是否存在,如果不存在,则表明对象已经被delete,丢弃该消息,如果指针被查到,则表明对象存在,可以放心的操作。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 属性定义:
*   DWORD           m_dwSendFileDossTime
*
* 类型:
*    缺省值=10,单位为毫秒。
*
* 说明:
*    表明每传送一个数据块时,线程的休眠时间。它的值决定了传送文件时的最快速度。值越小,传送速度越快,但CPU的占用率也越高,反之亦然。

    注意:  它只表示传送文件的最快速度,实际的传送速度会根据对方的接收速度和线路质量进行动态地调整。当对方的接收速度过慢或线路质量不好,造成不断地重传时,这个值会增加,以适应对方的接收速度。

       在传送过程中这个值一旦被增加,就不会再减少,因此它只表示传送的最快速度。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 属性定义:
*    LPPRECVINFO     m_lprRecvInfo
*
* 类型:
*    缺省值=NULL
*
* 说明:
*    指向PRECVINFO结构的指针。
     当线程类型为TASK_TCP_RECV或TASK_HTTP_RECV时,必需设定该值指向一个有效的PRECVINFO结构。

    关于PRECVINFO结构的说明,请查阅PDefine.h中的结构说明。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 属性定义:
*    LPPMSGINFO      m_lprMsgInfo
*
* 类型:
*    缺省值=&PDefine::rSMsgInfo。
*
* 说明:
*    指向PMSGINFO结构的指针。该结构内保存了接收DLL向外部发送消息时的相关参数。

     关于PMSGINFO结构的说明,请查阅PDefine.h中的结构说明。
     关于DLL向外部发送的消息的说明,请查阅PDefine.h中的消息说明。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 属性定义:
*    PFCALLBACK      m_pCallBackFun
*
* 类型:
*    缺省值=NULL
*
* 说明:
*    指向处理DLL发送的消息的回调函数的指针。
     如果设定了回调函数,则不再向窗口发送消息。

     注意:  应该尽量使用消息,而不要使用回调函数,即使使用了回调函数,也不要在函数中处理长延时的操作。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 属性定义:
*    PFriend*        m_pFriend
*
* 类型:
*    缺省值为空。
*
* 说明:
*    指向好友PFriend对象的指针。PFriend对象中保存了进行连接时所用到的IP地址和端口号。

       除了类型为TASK_HTTP_RECV时,不需要指定PFriend对象,其它的类型都必需指定PFriend对象,并且设定好PFriend对象中的IP地址和端口号。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 属性定义:
*    WORD            m_wSendMsgRate

*
* 类型:
*    缺省值=PDefine::wSendMsgRate,只有在类型为接收或传送时有效。
*
* 说明:
*    这个属性的值决定了当前PTask对象在传送和接收的过程中向DLL外部发送OMSG_SEND_DATA和OMSG_RECV_MSG消息时的速度。

 

十六 PBaseAct中的函数说明

* 函数名称:
*    GetCallBackMsg()
*
* 类型:
*    虚函数,如果派生类希望使用消息来处理所接收到的该类的实例,必需具体实现该方法。
*
* 参数:
*    无
*
* 返回值:
*    LPPMSGINFO              -指向PMSGINFO结构的指针或NULL。
*
* 说明:
*    当DLL接收到一个用户自定义对象时,首先会调用该函数,如果该函数返回为NULL,则调用GetParseActFunPointer()函数返回的回调函数来处理该指令对象。如果该函数返回了一个PMSGINFO结构的指针,则DLL将会向PMSGINFO结构中指定的窗体发送指定的消息。
   
       消息的lParam参数,保存了指向该对象的指针。
       在消息的响应函数的最后,应该delete这个指令对象,以释放内存。

      举例如下:
      LPPMSGINFO GetCallBackMsg()
      {
           return &PDefine::rSMsgInfo;
      }
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*    GetCallBackPointer()
*
* 类型:
*    不可覆盖的函数。
*
* 参数:
*    无
*
* 返回值:
*    PDHANDLE                    -接收该指令对象数据流的对象的句柄。
*
* 说明:
*    返回接收该指令对象数据流的对象的手柄。如果你在处理指令的过程中,需要通知接收该指令的SOCKET对象去实现一些特定的操作,可以通过调用PDefine::SNotifyConnectSrc()静态方法来实现一个通知。该函数返回的句柄是PDefine::SNotifyConnectSrc()方法所需要的参数。

      关于PDefine::SNotifyConnectSrc()方法请查阅PDefine.h文件中的函数说明。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*    GetObjType()
*
* 类型:
*    虚函数,派生类不要重载该函数。DLL内部定义的派生类,才使用标识。
*
* 参数:
*    无
*
* 返回值:
*    BYTE                        -自定义对象的标识。
*
* 说明:
*    该函数返回表示该对象的标识。重载该函数不会起任何作用。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   GetClassID()
*
* 类型:
*   虚函数,派生类必需具体实现该方法。
*
* 参数:
*   无
*
* 返回值:
*    LPCTSTR                     -派生类的ClassID,唯一标识一个类。
*
* 说明:
*    返回唯一标识派生类的ClassID。对于PBaseAct的派生类,必需规定一个唯一的ClassID。

      关于ClassID的命名,目前并没有一个统一的规定,可以是任意长度的一串字符。如果用户定义的类只在自己的程序中使用,则不需要重载该方法。

      ClassID可以由字符a..z、A..Z、0..9、_和+、- 、#等组成。

      ClassID使程序不但可以支持开发者自己创建的类,而且可以支持其他开发者创建的类,而不需要修改程序。

      开发者可以将自己定义的PBaseAct派生类和相应的类对象解析程序打包成一个DLL,直接发布出来,隐藏具体的实现细节,提供足够的接口,使其他开发者可以直接调用这些对象来完成指定的功能。但注意,在发布自己的派生类时,必需提供一个唯一的ClassID。

      关于ClassID的生成,可以参考OCX控件的ClassID的生成。

      注意:  ClassID对于每一个相同的类都是一样的,ClassID区别的是类,而不是对象。

      虽然ClassID可以唯一标识一个类,但是类名还是有可能重复,在每个人独立开发的情况下,这个问题肯定会存在的。

      解决的办法是可以采用类似于JAVA类的命名,使用域名+目录名+类名的方式来命名一个类,但中间不用使用'.'符号。

      如果你能够很好地将派生类与相应的指令解析程序封装到DLL中,而对外只提供接口,而不提供对对象的直接访问,那么你定义的派生类可以是任意的名字,因为它只在你的DLL内部创建和析构。

    举例如下:
    virtual LPCTSTR GetClassID()
    {
        return "ABCDE-12345-xxxxx-Ab12X";
    }
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   GetParseActFunPointer()
*
* 类型:
*    虚函数,如果派生类希望使用函数来处理所接收到的该类的实例,必需具体实现该方法。
*
* 参数:
*   无
*
* 返回值:
*   GETCALLBACK                 -回调函数的地址。
*
* 说明:
*    返回处理自定义的PBaseAct派生类对象的回调函数的地址。
      该函数和GetCallBackMsg()函数你只用实现一个,如果你重载了GetCallBackMsg()函数,则不需要再重载该函数,DLL会优先处理GetCallBackMsg()函数。

     如果你没有重载GetCallBackMsg()函数,则你必需重载该函数,否则自定义的指定对象会被删除,而得不到处理。

    注意:  如果你重载了该函数,则在回调函数的最后,应该Delete传递的指令对象。

    关于回调函数的原形请查阅PDefine.h文件中的回调函数说明。

    举例如下,其中GlobalFunParseUserObj()函数是一个GETCALLBACK回调函数:
    virtual GETCALLBACK* GetParseActFunPointer()
    {
        return GlobalFunParseUserObj;
    }
   
    也可以为每一个派生类指定一个不同的处理函数,这时无需比较类型,每个派生类的处理函数都是该派生类中的一个静态方法。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   InitObject()
*
* 类型:
*   虚函数,派生类必需具体实现该方法。该函数由DLL在反序列化时自动调用。
*
* 参数:
*   PDHANDLE    handle          -对象的句柄。
*
* 返回值:
*   无
*
* 说明:
*   该函数实现指令对象的反序列化,将数据流中传递的对象的各属性的具体值传递给对象中相应的属性。

    举例如下:
    virtual void InitObject(PDHANDLE handle);
    {  
        //该方法的第一句必需调用基类的方法。
        PBaseAct::InitObject(handle);

        //按照你在SelfSerialize()方法中序列化属性时的顺序,
        //依次调用静态方法int SGetValue(data,&value)
        //其中的value是属性的变量名称,可以是一个CString、int或CStringEx类型的变量。
           
        //SGetValue()方法会返回当前属性的顺序号。顺序号从2开始计数。
        //顺序号的0是传送者ID,1是该对象的版本号。在基类的方法中会自动分解得到这些值。
    }
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   SelfSerialize()
*
* 类型:
*    虚函数,派生类必需具体实现该方法。该函数在需要传递指令对象时序列化对象。
*
* 参数:
*   char*              src                -保存指令序列化成数据流的缓冲区的地址缓冲区的大小可以为NULL或任意长度,在序列化的过程中缓冲区的大小会根据需要而增加,但不会减少。
*   DWORD&      dwLen           -当前数据流的长度,这个值会在序列化过程中改变。
*   DWORD&      dwBufferLen  -缓冲区的长度,这个值会在序列化过程中改变。
*
* 返回值:
*   char*                                  -数据流缓冲区的地址。始终应该将返回的值赋与保存缓冲区地址的变量。如果缓冲区的尺寸小于数据流的尺寸,则DLL会负责重新创建一个足够大小的缓冲区,原缓冲区的资源会被释放。
*
* 说明:
*    该函数实现指令对象的序列化,以形成可以由SOCKET传送的数据流。

    举例如下:
    virtual char* SelfSerialize(char* src,DWORD& dwLen,DWORD& dwBufferLen)
    {  
        //首先要清空指令的长度。
        dwLen=0;
        {
            //将想序列化的属性依次调用PBaseAct::SCountLen()方法,计算对象的长度。
            //下面是以三种不同的类型举的例子,在实际的派生类中根据想传输的属性
            //调用SCountLen()方法。

            //计算一个BYTE类型的属性m_byValue的长度,传递的是值。
            PBaseAct::SCountLen(dwLen,this->m_byValue);

            //计算一个CStringEx类型的属性m_cEx的长度,传递的是地址。
            PBaseAct::SCountLen(dwLen,&this->m_cEx;);

            //计算一个CString类型的属性m_strString的长度,传递的是地址。
            WORD i=PBaseAct::SCountLen(dwLen,this->m_strString,this->m_strString.GetLength());
        }

        //等想序列化的属性都调用SCountLen()方法计算了长度后,
        //调用SInitUniteValue()静态方法初始化对象流。
        src=PBaseAct::SInitUniteValue(src,dwLen,dwBufferLen,this);
        {
            //然后调用SUniteValue()方法依次序列化属性的值,以形成数据流。
            //下面是以三种不同的类型举的例子,在实际的派生类中根据想传输的属性
            //调用SUniteValue()方法。

            //序列化BYTE类型的属性m_byValue,传递的是值。
            this->SUniteValue(src,dwLen,this->m_bynValue);

            //序列化CStringEx类型的属性m_cEx,传递的是地址。
            this->SUniteValue(src,dwLen,&this->m_cEx);

            //序列化CString类型的属性m_strString,传递的是地址。
            //i值是前面调用SCountLen()时被传回的值。
            this->SUniteValue(src,dwLen,this->m_strString,i);
        }

        //在函数的最后,一定要调用基类的SelfSerialize()方法。
        PBaseAct::SelfSerialize(src,dwLen,dwBufferLen);
       
        //返回序列化后所产生的数据流。
        return src;
    }
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   SCountLen()
*
* 类型:
*    protected 静态函数。该方法只应该在SelfSerialize()方法中调用。
*
* 参数:
*   DWORD&      dwLen       -指令字的有效长度。该参数应该直接使用SelfSerialize()方法中传递的第2个参数dwLen。
*   int                  value          -一个int类型的PBaseAct派生类中的属性的值。
*
* 返回值:
*   无
*
* 说明:
*   计算一个int类型的属性的长度。
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   SCountLen()
*
* 类型:
*   protected 静态函数。该方法只应该在SelfSerialize()方法中调用。
*
* 参数:
*   DWORD&      dwLen       -指令字的有效长度。该参数应该直接使用SelfSerialize()方法中传递的第2个参数dwLen。
*   CStringEx*      pEx           -一个CStringEx类型的PBaseAct派生类中的属性的地址。
*
* 返回值:
*   无
*
* 说明:
*   统计CStringEx类型的属性的长度。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   SCountLen()
*
* 类型:
*   protected 静态函数。该方法只应该在SelfSerialize()方法中调用。
*
* 参数:
*   DWORD&      dwLen          -指令字的有效长度。该参数应该直接使用SelfSerialize()方法中传递的第2个参数dwLen。
*   LPCTSTR       value            -一个CString类型的PBaseAct派生类中的属性的数据缓冲区指针。
*   DWORD         dwCount=0   -字符串的长度。可缺省。最好是给出,否则程序将自动计数字符串缓冲区的长度。字符串必需以'\0'作为终结符。
*
* 返回值:
*   DWORD                             -当前字符串的长度。
*
* 说明:
*   统计CString类型的属性的长度。
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   SGetValue()
*
* 类型:
*   protected 静态函数。该方法只应该在InitObject()方法中调用。
*
* 参数:
*   PDHANDLE    handle      -对象的句柄,由InitObject()方法传递。
*   CString*         src           -一个CString类型的PBaseAct派生类中的属性的地址。
*
* 返回值:
*   无
*
* 说明:
*   从数据流中得到一个字符串,并赋给指定的CString对象。
*  
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   SGetValue   ()
*
* 类型:
*   protected 静态函数。该方法只应该在InitObject()方法中调用。
*
* 参数:
*   PDHANDLE    handle      -对象的句柄,由InitObject()方法传递。
*   int*                 src          -一个int类型的PBaseAct派生类中的属性的地址。
*
* 返回值:
*   无
*
* 说明:
*   从数据流中得到一个int值,并赋给指定的int对象。
*  
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   SGetValue()
*
* 类型:
*   protected 静态函数。该方法只应该在InitObject()方法中调用。
*
* 参数:
*   PDHANDLE    handle      -对象的句柄,由InitObject()方法传递。
*   CStringEx*      src          -一个CStringEx类型的PBaseAct派生类中的属性的地址。
*
* 返回值:
*   无
*
* 说明:
*   从数据流中得到一个二进制流缓冲,并填充数据到指定的CStringEx对象中。
*  
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   SInitUniteValue()
*
* 类型:
*   protected 静态函数。该方法只应该在SelfSerialize()方法中调用。
*
* 参数:
*   char*           src                 -形成数据流的缓冲区的首地址。由SelfSerialize()方法传递。
*   DWORD&    nLen              -数据流的有效长度。由SelfSerialize()方法传递。
*   DWORD&    dwBufferLen  -数据流缓冲区的尺寸。由SelfSerialize()方法传递。
*   PBaseAct*    pb                  -想序列化的对象的指针。应该传递this。
*
* 返回值:
*   char*                                -新的数据流的缓冲区的首地址。应该赋于src。
*
* 说明:
*   初始化数据流。
*  
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   SUniteValue()
*
* 类型:
*   protected 静态函数。该方法只应该在SelfSerialize()方法中调用。
*
* 参数:
*   char*            src      -形成数据流的缓冲区的首地址。由SelfSerialize()方法传递。
*   DWORD&    nLen    -数据流的有效长度。由SelfSerialize()方法传递。
*   int                value    -想序列化的int属性的值。
*
* 返回值:
*   无
*
* 说明:
*   将整数value的值增加到数据流中。
*  
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   SUniteValue()
*
* 类型:
*   protected 静态函数。该方法只应该在SelfSerialize()方法中调用。
*
* 参数:
*   char*         src             -形成数据流的缓冲区的首地址。由SelfSerialize()方法传递。
*   DWORD& nLen           -数据流的有效长度。由SelfSerialize()方法传递。
*   LPCTSTR  value          -想序列化的CString对象的数据缓冲区的首地址。
*   DWORD    dwCount=0 -CString对象的字符串数据的长度。
*
* 返回值:
*   无
*
* 说明:
*   将字符串value增加到数据流中。
*  
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 函数名称:
*   SUniteValue()
*
* 类型:
*   protected 静态函数。该方法只应该在SelfSerialize()方法中调用。
*
* 参数:
*   char*            src       -形成数据流的缓冲区的首地址。由SelfSerialize()方法传递。
*   DWORD&    nLen     -数据流的有效长度。由SelfSerialize()方法传递。
*   CStringEx*   value     -想序列化的CStringEx对象的首地址。一个CStringEx对象表示一个二进制流缓冲区。
*
* 返回值:
*   无
*
* 说明:
*   将一个二进制流缓冲区中的数据增加到数据流中。

 

十七 PBaseAct类中的属性说明

* 属性定义:
*   CString         m_strSender
*
* 说明:
*   发送该指令对象者的ID。
*
*
*   *   *   *   *   *   *   *   *   *   *   *   *
* 属性定义:
*   WORD            m_wOrderNo
*
* 说明:
*   指令的顺序号,该值不需要用户指定。(暂时保留)

本文地址:http://com.8s8s.com/it/it2368.htm