下面是本人设计的数据包,有些缺陷
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缓冲区多大,那我的包该设计多大。可能还有更多缺陷,希望有人指点改善这些缺陷的有效方法。本帖分数已经给的比较高,希望有人来得到这个分数。
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缓冲区多大,那我的包该设计多大。可能还有更多缺陷,希望有人指点改善这些缺陷的有效方法。本帖分数已经给的比较高,希望有人来得到这个分数。
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;
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的封包接口,模仿一下。
typedef struct LOGON_OFF_CANCEL
{
DWORD buffer_length; // buffer 长度
DWORD total_client; // buffer中存放了多少个客户信息结构体
CHAR buffer[1]; // 客户信息结构体内容
}LOGON_OFF_CANCEL; 楼上把将buffer[1024]长度变为1实在不明白什么意思
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;
...登录过程处理
}够简单了吧。
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);
接收处理,都一样