应用层自定义的命令包
#pragma pack(1)
typedef struct _tagRecvType
{
int nLength; //当前包的总长度
BYTE Tag; //标记,值为0X55
BYTE Command; //自定义的应用层协议,为0X01的时候是登陆,0X02的时候为传送数据
char chContent[1024]; //数据内容
}RecvType;
#pragma pack()然后是对客户端的消息处理:
int nRet = 0; //每次接收到的数据的长度
int nPackageLength = 0; //当前收到的包的长度
int nRest = MAX_BUFFER_SIZE; //收到一个完整的包还差的字节
int nRecvLength = 0; //当前收到的字节数
char buf[MAX_BUFFER_SIZE+1] = {0}; //接收数据缓存
CWSocket wsk;
wsk = s;
while(1)
{
info.Empty();
//接收数据,一次收一个完整的数据包
while(nRest > 0)
{
nRet = wsk.ReadData(buf+nRecvLength, nRest, 60);
nRecvLength += nRet;
char* pTemp = strchr(buf, 0x55);
int nTemp = pTemp - buf;
char chTemp[8] = {0};
strncpy(chTemp, buf, nTemp);
nPackageLength = atoi(chTemp);
nRest = nPackageLength - nRet;
}
buf[nPackageLength] = '\0';
RecvType* pRecvType = (RecvType*)buf;
if(pRecvType->Command == 0x01) //登陆
{
}
if(pRecvType->Command == 0x02) //发送数据
{
}
}首先想请大家帮我看看,这样写,功能是否实现,还有就是哪里写得不好希望大家指出来,能帮我改一下更好了,谢谢了。
#pragma pack(1)
typedef struct _tagRecvType
{
int nLength; //当前包的总长度
BYTE Tag; //标记,值为0X55
BYTE Command; //自定义的应用层协议,为0X01的时候是登陆,0X02的时候为传送数据
char chContent[1024]; //数据内容
}RecvType;
#pragma pack()然后是对客户端的消息处理:
int nRet = 0; //每次接收到的数据的长度
int nPackageLength = 0; //当前收到的包的长度
int nRest = MAX_BUFFER_SIZE; //收到一个完整的包还差的字节
int nRecvLength = 0; //当前收到的字节数
char buf[MAX_BUFFER_SIZE+1] = {0}; //接收数据缓存
CWSocket wsk;
wsk = s;
while(1)
{
info.Empty();
//接收数据,一次收一个完整的数据包
while(nRest > 0)
{
nRet = wsk.ReadData(buf+nRecvLength, nRest, 60);
nRecvLength += nRet;
char* pTemp = strchr(buf, 0x55);
int nTemp = pTemp - buf;
char chTemp[8] = {0};
strncpy(chTemp, buf, nTemp);
nPackageLength = atoi(chTemp);
nRest = nPackageLength - nRet;
}
buf[nPackageLength] = '\0';
RecvType* pRecvType = (RecvType*)buf;
if(pRecvType->Command == 0x01) //登陆
{
}
if(pRecvType->Command == 0x02) //发送数据
{
}
}首先想请大家帮我看看,这样写,功能是否实现,还有就是哪里写得不好希望大家指出来,能帮我改一下更好了,谢谢了。
首先char chContent[1024]; //数据内容
从你定义的协议来看,你是定长的数据包,就没必要用标记。
从我理解的你的CWSocket类来些点代码吧。
while(1)
{
info.Empty();
//接收数据,一次收一个完整的数据包
nRet = wsk.ReadData(buf, MAX_BUFFER_SIZE, 60);
//60应该是不超时,nRet 是返回接收到的实际数据包大小吧。还有我认为接收数据包的缓存要在wsk内去实现
if(nRet >= sizeof(RecvType))
{
RecvType* pRecvType = (RecvType*)buf;
if(pRecvType->Command == 0x01) //登陆
{
}
if(pRecvType->Command == 0x02) //发送数据
{
}
//这里还要去wsk减去sizeof(RecvType)大小的缓存,因为这里处理了一个数据包。
}
}
帖一下类里面的代码:
int CWSocket::ReadData(char FAR* buf, int len, int timeout)
{
if(!m_bConnected || m_sSocket == NULL)
{
err = -1;
return -1;
} HANDLE hThread;
DWORD dwThreadId;
TPARA para; para.OutTime = timeout;
para.s = m_sSocket;
para.bExit = FALSE;
para.IsExit = FALSE;
para.pbConnected = &m_bConnected;
hThread = CreateThread(NULL, NULL, TimeoutControl, (LPVOID)(¶), 0, &dwThreadId);
if (hThread == NULL) return -1; int nRet = recv(m_sSocket, buf, len, 0);
if(nRet == SOCKET_ERROR) err = WSAGetLastError(); para.bExit = TRUE;
while(!para.IsExit) Sleep(1); return nRet;
}这个类是别人写的,如果客户端发送包的时候,chContent里只写了少数几个字符,那么接收到的也是1024字节长的数据么?不太清楚这个,就弄了个标记。
一般来讲你这个数据包才1k多点,一般不会粘包。
为了万一可以这么做。 int nRet = 0; //每次接收到的数据的长度
int nPackageLength = sizeof(RecvType); //一个包的长度
int nRest = MAX_BUFFER_SIZE; //收到一个完整的包还差的字节
int nRecvLength = 0; //当前收到的字节数
char buf[MAX_BUFFER_SIZE*10] = {0}; //数据缓冲区
CWSocket wsk;
wsk = s;
while(1)
{
info.Empty();
//接收数据,一次收一个完整的数据包
nRet = wsk.ReadData(buf+nRecvLength, MAX_BUFFER_SIZE, 60);
nRecvLength += nRet;
buf[nRecvLength] = '\0';
if(nRecvLength >= nPackageLength)
{
RecvType* pRecvType = (RecvType*)buf;
if(pRecvType->Command == 0x01) //登陆
{
}
if(pRecvType->Command == 0x02) //发送数据
{
}
nRecvLength -= nPackageLength;
memmove(buf,buf + nPackageLength,nRecvLength);
}
sleep(15);
}
DWORD CALLBACK CWSocket::TimeoutControl(LPVOID lpParm)
{
TPARA* para = (TPARA*)lpParm;
time_t stime = time(NULL);
BOOL bTimeover = FALSE; while(!bTimeover)
{
if(para->bExit)
{
para->IsExit = TRUE;
return 0;
} Sleep(1); time_t ntime = time(NULL);
if((ntime - stime) > para->OutTime) bTimeover = TRUE;
} if(para->bExit)
{
para->IsExit = TRUE;
return 0;
} if(para->s != NULL)
{
para->pbConnected[0] = FALSE;
shutdown(para->s, SD_RECEIVE);
Sleep(5);
closesocket(para->s);
} para->IsExit = TRUE;
return 0;
}