下面是本人设计的数据包,有些缺陷
typedef struct TYPE_PACKET
{
DWORD cmd_type;                                          // 消息包类型
union
{
LOGON_OFF_CANCEL packet_loc;                         // 用户上线,下线,服务端退出
SOURCE_DESCRITPION_INFO packet_stca;                 // (服务端----->客户端)
CLIENT_TO_CLIENT_FILE_READY packet_ctcfr;            // 客户端询问客户端接收文件是否准备好           (客户端<---->客户端)
CLIENT_TO_CLIENT_FILE_AGREE packet_ctcfa;            // 客户端同意接收文件                           (客户端<---->客户端)          
CLINT_TO_CLIENT_FILE packet_ctcf;                    // 客户端发送文件给客户端                       (客户端<---->客户端)
CLIENT_TO_CLIENT_MSG packet_ctcm;                    // 客户端发送消息                               (客户端<---->客户端)
};
}TYPE_PACKET;
// 用户上线,下线,服务端退出
typedef struct LOGON_OFF_CANCEL
{
DWORD total_client;            // buffer中存放了多少个客户信息结构体
DWORD buffer_length;           // buffer 长度
CHAR  buffer[1024];            // 客户信息结构体内容
}LOGON_OFF_CANCEL;缺陷一:LOGON_OFF_CANCEL CLINT_TO_CLIENT_FILE 等包的设计都是定长包,没法根据实际长度传送数据,浪费了资源,没有很刚好的控制要传送的内容。
同时接收方又能知道传了多少,而且能很简单便捷的接收这些包。缺陷二:长度不知道是否设计合理,如果用来发送大文件,buffer依然设计为1024是否小了,或者大了。不知道tcp缓冲区多大,那我的包该设计多大。可能还有更多缺陷,希望有人指点改善这些缺陷的有效方法。本帖分数已经给的比较高,希望有人来得到这个分数。

解决方案 »

  1.   

    // 用户上线,下线,服务端退出 
    typedef struct LOGON_OFF_CANCEL 

    DWORD total_client;            // buffer中存放了多少个客户信息结构体 
    DWORD buffer_length;          // buffer 长度 
    CHAR  buffer[1024];            // 客户信息结构体内容 
    }LOGON_OFF_CANCEL; 
    =============================================这样设计
    typedef struct LOGON_OFF_CANCEL 

    DWORD buffer_length;          // buffer 长度 
    DWORD total_client;            // buffer中存放了多少个客户信息结构体 
    CHAR  buffer[1];            // 客户信息结构体内容 
    }LOGON_OFF_CANCEL; 
    收到数据后LOGON_OFF_CANCEL* logon = (LOGON_OFF_CANCEL*)pdata;
      

  2.   

    VNC协议,又传控制命令,又传图象数据。
      

  3.   

    // 用户上线,下线,服务端退出 
    typedef struct LOGON_OFF_CANCEL 

    DWORD total_client;            // buffer中存放了多少个客户信息结构体 
    DWORD buffer_length;          // buffer 长度 
    CHAR  buffer[1024];            // 客户信息结构体内容 
    }LOGON_OFF_CANCEL; 
    ============================================= 这样设计 
    typedef struct LOGON_OFF_CANCEL 

    DWORD buffer_length;          // buffer 长度 
    DWORD total_client;            // buffer中存放了多少个客户信息结构体 
    CHAR  buffer[1];            // 客户信息结构体内容 
    }LOGON_OFF_CANCEL; 
    收到数据后 LOGON_OFF_CANCEL* logon = (LOGON_OFF_CANCEL*)pdata; 就按照这样处理,
    你可以看看TCP/IP的封包接口,模仿一下。
      

  4.   

    这样设计 
    typedef struct LOGON_OFF_CANCEL 

    DWORD buffer_length;          // buffer 长度 
    DWORD total_client;            // buffer中存放了多少个客户信息结构体 
    CHAR  buffer[1];            // 客户信息结构体内容 
    }LOGON_OFF_CANCEL; 楼上把将buffer[1024]长度变为1实在不明白什么意思
      

  5.   

    我的是这样:
    struct TPkgHead
    {
    uchar headFlag;
    uint16  crc16;
    uint16  len; 
    }; struct THead
    {
    enum{current_version = 1};
    uchar ver;
            uint16  cmd; // command
    }
    struct TLogin:public THead 
    {
       TLogin(){cmd = 0x00;} //在ctor初始化命令类型
    }
    发登录请求:
    TLogin login;
    ...
    TPkgHead head;
    head.len = sizeof(login); //体长
    ...
    send(&head, sizeof(head));
    send(&login, sizeof(login));收数据,假设收够TPkgHead 大小:
    TPkgHead * pPkgHead = (TPkgHead *)sockBuffer;
    再从头得到体大小:
    int bodyLen = pPkgHead->len;
    再收够体大小,
    最后:
    THead* pHead = (THead*)socketBodyBuffer;//转换体数据成结构
    switch(pHead->cmd)
    {
     case 0x00: //这是登录包了
    {
    TLogin* pLogin = (TLogin*)pHead;
    ...登录过程处理
    }够简单了吧。
      

  6.   

    对付变数结构:
    struct Item 
    {
    ...
    }
    struct List :public THead
    {
      int count;
      Item items[1];
    }char buf[足够大] = {0};
    List * pList = (List*)buf;
    pList->cmd = ...
    pList->count = 100;
    for(int i = 0 ; i < pList->count; ++i)
    {
    pList->items[i] = ...初始化
    }发送头:
    TPkgHead head; 
    head.len = 自已算//体长 
    ...
    send(&head, sizeof(head)); 
    发送体:
    send(pList, head.len);
    接收处理,都一样
      

  7.   

    你有buffer大小疑问,其实是你自己被困在单个struct大小的思维里了。CHAR  buffer[1]通常要借助于外面的缓冲区,用它来给数据缓冲区进行初始化什么的。
      

  8.   

    Cowboy22 的回复使得本帖有了一个很令人满意的答案,你至少可以得到一半的分数了。但是CHAR  buffer[1]通常要借助于外面的缓冲区,用它来给数据缓冲区进行初始化什么的。CHAR  buffer[1]通常要借助于外面的缓冲区?这句话没能明白,能否举个例子呢?在此感谢Cowboy22踊跃讨论。
      

  9.   

    Item和List结构不是已经给出了例子?你把Item换成CHAR差不多接近你想要的例子了。