我使用的是indy tcpclient控件,接受包定义如下:
/************************************************接受数据格式定义********************************************************/
  Type PHead = packed record
      _head           :LongInt;   //MARK 标志
      _streamLength   :LongInt;   //报文长度
      _command        :LongInt;   //命令 8004流媒体数据
      _Order          :LongInt;   //序列
      _Value          :LongInt;
  End;
  Type PResvVideoMsg11 =  record
      _FrameOrder     :Word ;//:array[0..1] of byte ;
      _FrameType      :array[0..0] of byte  ;
      _AfterPackCount :array[0..0] of byte ;
      _Times          :array[0..7] of byte ;
      _CodeType       :array[0..1] of byte  ;
      _Cannel         :array[0..1] of byte ;
      _Memo1          :array[0..1] of byte  ;
      _Memo2          :array[0..1] of byte ;
      _slip           :array[0..39] of byte ;
      _stream         :array[0..10199] of byte ;  //流媒体缓冲区
  End;
/**************************************************************************************************************************//

解决方案 »

  1.   

    接受数据时另启一线程,线程接受数据代码如下:
    使用 while 标志 do
                   过程 ;
             end
    /*****************************************************接受数据过程***************************************************/
      IdTcpClient.ReadBuffer(FHead._head,4);//包头
      IdTcpClient.ReadBuffer(FHead._streamLength,4);//长度
      IdTcpClient.ReadBuffer(FHead._command,4);//命令
      IdTcpClient.ReadBuffer(FHead._Order,4);
      IdTcpClient.ReadBuffer(FHead._Value,4);
      IF  Fhead._command = 8004 Then  //表示该包为媒体数据
      Begin
         IdTcpClient.ReadBuffer( FData._FrameOrder,2);
         IdTcpClient.ReadBuffer( FData._FrameType,1);
         IdTcpClient.ReadBuffer( FData._AfterPackCount,1);
         IdTcpClient.ReadBuffer( FData._Times,8);
         IdTcpClient.ReadBuffer( FData._CodeType,2);
         IdTcpClient.ReadBuffer( FData._Cannel,2);
         IdTcpClient.ReadBuffer( FData._Memo1,2);
         IdTcpClient.ReadBuffer( FData._Memo2,2);
         IdTcpClient.ReadBuffer(FData._slip ,40  );     //包头与自定义帧头
         IdTcpClient.ReadBuffer(FData._stream,10120 ); //视频流
         Fmsg.FrameIndex:=   FData._FrameOrder ;
        // setstream.Write(FData._stream, 10120 );    写入文件
         SendMessage( PUB_HWND , _WM_THREAD_INCA ,0, longint(@Fmsg)) ;  //通知主窗口刷新帧序号  End Else IF FHead._command = 8001 Then
      Begin
        // SetLength(sXml, FHead._streamLength );
         IdTCPClient.ReadBuffer(sXml, sizeof(sXml) );
      End
      

  2.   

    现在的问题是,当正确接受一次数据后,在下一包就不能正确解析,要等待1、2秒后过来的数据又能正确解析了。 FData._FrameOrder 为对方定义的帧序号,按理说应该是连贯数,但是通过跑起来以后显示的请看,该值不连贯,不能连续正确解析后续包头和帧头?请大神指点迷津!
      

  3.   

    /*************************************对方发的VC中的定义*************************************************/
    /**************************************************************************
    * Copyright (c) 2011,ChengDu ThinkWatch Company
    * All rights reserved.
    *--------------------------------------------------------------------------
    * 文件名称: VProtocol.h
    * 简要说明: 公共协议头文件
    * 相关描述:
    * 编写作者: Sober.Peng
    * 完成日期: 2013-5-17
    *--------------------------------------------------------------------------
    * 修订作者:
    * 修订时间:
    *--------------------------------------------------------------------------
    **************************************************************************/
    #ifndef VPROTOCOL_H
    #define VPROTOCOL_H#include "sysinc.h"
    #include "vutils.h"#define SZ_1K       (1024)
    #define SZ_1M       (SZ_1K * SZ_1K)///数据长度////////////////////////////////////////////////////////////////////////////////
    #define LEN_UUID    (32)    // UUID(设备串号、手机号)
    #define LEN_NAME    (32)    // 名字(用户名、设备名)
    #define LEN_PWD     (32)    // 密码#define LEN_TIME    (32)    // 时间#define LEN_HOST    (20)    // IP地址
    #define LEN_MAC     (20)    // MAC地址#define LEN_PATH    (128)   // 路径长
    #define LEN_STRING  (128)   // 字符串
    #define LEN_LOG     (256)   // 日志#define LEN_MD5     (36)    // MD5长度#define LEN_PHOTO   (127*SZ_1K) // 照片#define LEN_PLATE   (12)    // 车牌号#define ARRAY_SIZE  (8)     // 数组最大个数#define LEN_RECV    (32*SZ_1K)  // 网络接收包大小
    #define LEN_SEND    (128*SZ_1K) // 网络发送包大小///编码类型////////////////////////////////////////////////////////////////////////////////
    typedef enum
    {
        CODE_ID_G711A  = 19,
        CODE_ID_JPEG   = 26,
        CODE_ID_AAC    = 37,
        CODE_ID_H264   = 96,
        CODE_ID_MJPEG  = 1002,
    }E_CODE_ID;
    #define EFRM_I      3       // I帧
    #define EFRM_P      2       // P帧
    #define EFRM_B      1       // B帧
    #define EFRM_ADO    4       // 音频///分辨率//////////////////////////////////////////////////////////////////////////////////
    //typedef enum
    //{
    //    E_VSZ_QVGA = 0, // 320  * 240
    //    E_VSZ_CIF,      // 352  * 288
    //    E_VSZ_VGA,      // 640  * 480
    //    E_VSZ_SVGA,     // 800  * 600
    //    E_VSZ_D1,       // 720  * 576
    //    E_VSZ_XGA,      // 1024 * 768
    //    E_VSZ_720P,     // 1280 * 720
    //    E_VSZ_2M_43,    // 1600 * 1200
    //    E_VSZ_1080P,    // 1920 * 1080
    //    E_VSZ_3M_43,    // 2048 * 1536
    //    E_VSZ_5M_43,    // 2592 * 2944
    //    E_VSZ_5M_169,   // 3072 * 1728
    //    E_VSZ_QCIF,     // 176 * 144
    //} E_VDO_SIZE;typedef enum{
        VI_CHN_0   = 0, // 视频0
        VI_CHN_1   = 1, // 视频1
        VI_CHN_2   = 2, // 视频2
        VI_CHN_MAX = 2, // 视频最大    AI_CHN_0   = 3, // 音频通道0
        AV_CHN_MAX = 3, // 总共4通道    IVA_DBG_0  = 10,// 算法调试通道
    } AV_CHN;// 01.00.00版本
    #define _VERSION_SOFTWARE   (0x1000) // 软件总体版本
    #define _VERSION_HARDWARE   (0x1000) // 硬件总体版本#define _VERSION_STRING     ("v1.0.00") // 
    #define _SYSTEM_STRING      ("thinkwatch_whs_ds")
    #define _VERSION_STREAM     (0x2)       // #pragma pack(2)
    ///包结构定义//////////////////////////////////////////////////////////////////////////////
    const THK_U32 HEAD_MARK = 257;  // 包头// 包头
    struct TAG_PkgHead
    {
        THK_U32 nMark;      // 257
        THK_S32 nPkgLen;    // 数据长度(不包括包头)
        THK_S32 eCmdMain;   // 主命令类型
        THK_S32 eCmdMinor;  // 次命令类型
        TAG_PkgHead() {
            nMark           = 0;
            nPkgLen         = 0;
            eCmdMain        = 0;
            eCmdMinor       = 0;
        }
    };
    const THK_S32 HEAD_LENGTH = (THK_S32)sizeof(struct TAG_PkgHead);struct TAG_PkgHeadReq : public TAG_PkgHead 
    {
        THK_S8 sSrc[LEN_UUID];  // 
        THK_S8 sDst[LEN_UUID];  //     TAG_PkgHeadReq()
            : TAG_PkgHead()
        {
            memset(sSrc, 0, LEN_UUID);
            memset(sDst, 0, LEN_UUID);
        }
    };
    const THK_S32 HEAD_LEN_REQ = (THK_S32)sizeof(struct TAG_PkgHeadReq);
    inline THK_S32 PkgHeadReq(THK_S8* pPacket, THK_S32 eCmd, THK_U32 nParam,
        const THK_S8* pData, THK_S32 nData, const THK_S8* pSrc=NULL, const THK_S8* pDst=NULL)
    {
        if (!pPacket)
            return 0;    TAG_PkgHeadReq* pHead = (TAG_PkgHeadReq*)pPacket;
        memset(pHead, 0, HEAD_LEN_REQ);
        pHead->nMark        = HEAD_MARK;
        pHead->eCmdMain     = eCmd;
        pHead->eCmdMinor    = nParam;
        pHead->nPkgLen      = nData;    if (pSrc)
            memcpy(pHead->sSrc, pSrc, sizeof(pHead->sSrc));    if (pDst)
            memcpy(pHead->sDst, pDst, sizeof(pHead->sDst));    if (pData)
            memcpy(pPacket+HEAD_LEN_REQ, pData, nData);    return HEAD_LEN_REQ+nData;
    }struct TAG_PkgHeadResp : public TAG_PkgHead 
    {
        THK_S32 nResult;    TAG_PkgHeadResp()
            : TAG_PkgHead()
        {
            nResult = 0;
        }
    };
    const THK_S32 HEAD_LEN_RESP = (THK_S32)sizeof(struct TAG_PkgHeadResp);
    inline THK_S32 PkgHeadResp(THK_S8* pPacket, THK_S32 eCmd,
        const THK_S8* pData, THK_S32 nData, THK_S32 nRet, THK_S32 eMinor)
    {
        if (!pPacket)
            return 0;    TAG_PkgHeadResp* pHead = (TAG_PkgHeadResp*)pPacket;
        memset(pHead, 0, HEAD_LEN_RESP);
        pHead->nMark        = HEAD_MARK;
        pHead->eCmdMain     = eCmd;
        pHead->eCmdMinor    = eMinor;
        pHead->nPkgLen      = nData;
        pHead->nResult      = nRet;    if (pData)
            memcpy(pPacket+HEAD_LEN_RESP, pData, nData);    return HEAD_LEN_RESP+nData;
    }
    //////////////////////////////////////////////////////////////////////////
    // 数据流包头
    struct TAG_PkgHeadStream : public TAG_PkgHead
    {
        THK_S32         nResult;    THK_U16         nSeq;
        THK_U8          eFrm;
        THK_U8          nLast;
        THK_U64         nTime;    THK_U16         eCode;  // E_CODE_ID
        THK_S16         nChnx;  // channel
        THK_U16         nRvd1;  // sample-width
        THK_U16         nRvd2;  // bitrate-height    TAG_PkgHeadStream() 
            : TAG_PkgHead()
        {
            nResult     = 0;        nSeq        = 0;
            eFrm        = 0;
            nLast       = 0;
            nTime       = 0;        eCode       = 0;
            nChnx       = 0;
            nRvd1       = 0;
            nRvd2       = 0;
        }
    } ;
    const THK_S32 HEAD_LEN_STR = HEAD_LENGTH + 4;
    const THK_S32 STREAM_BEGIN = (THK_S32)sizeof(struct TAG_PkgHeadStream);
    inline THK_VOID PkgHeadStream(struct TAG_PkgHeadStream* pHead, THK_S32 eCmd)
    {
        if (!pHead)
            return;    memset(pHead, 0, sizeof(TAG_PkgHeadStream));
        pHead->nMark        = HEAD_MARK;
        pHead->eCmdMain     = eCmd;
        pHead->eCmdMinor    = 0x7c;
        pHead->nPkgLen      = STREAM_BEGIN-HEAD_LEN_STR;    pHead->nResult      = 0;    pHead->nSeq         = 0;
        pHead->eFrm         = (THK_U8)3;
        pHead->nLast        = (THK_U8)0;
        pHead->nTime        = VUtils::VGetTimeval();
    }
    #pragma pack()#define XML_ROOT    ("Message")
    #define XML_HEAD    ("<?xml version=\"1.0\" encoding=\"GBK\"?>\r\n")#endif // UTPROTOCOL_H
      

  4.   

    给我的感觉就像是按照10K去读缓冲区没读完,单步调试的时候,P帧和I帧第一次出现能解析正确,按照10k读取了缓冲区以后,再次读入的数据按理说就应该解析成包头和帧头。但是解析出来是错的。
      

  5.   

     IdTcpClient.ReadBuffer(FData._stream,10120 ); //视频流感觉10120有问题,  一般视频流多大, 那边就发多少,  然后你ReadBuffer的时候也是读多少, 不然浪费带宽