不管阻塞接收还是异步接收,总是绕不开数据流的分割问题。然而不知道什么原因,网上竟然很难找到现成、合用的代码,也许这种问题不值得付诸于代码,或者不太容易写出普遍通用的代码吧,但不论如何,轮到自己,个人觉得还是应该细致的做个总结。
抛开一些复杂因素,有助于清晰思路,更容易找到解决问题的办法,所以决定从最简单、也相当富有代表性的阻塞套接字开始研究,省略掉一些对所涉问题关系不是很大的代码,保留关键部分,如下:
int i_save_size;//尾巴数据长度
char c_save[2000];//保存上次接收的尾巴数据
char c_recv[2000];//数据接收缓冲区
u_long _stdcall thread_recv(void *arg)
{
... ...
while(TRUE)
{
i_eax=::recv(h,c_recv,2000,0);
if(SOCKET_ERROR==i_eax)
{
::closesocket(h); break;
}
data_patition(c_recv,i_eax,c_save,&i_save_size);//分割数据流
}
return 0;
}
假设数据包格式为:4字节包头+不定长包体,那么我们假设一种情况,recv拷贝到长度2000字节的数据,其中包括两个整包(1500字节,498字节),一个残缺包(2字节),这种情况当然需要做一些处理,处理过程如下:
int data_patition(char *c_data,int i_eax,char *c_save,int *p_save_size)
{
int i_rest=i_eax; char *p_rest=c_data; int i_size;
抛开一些复杂因素,有助于清晰思路,更容易找到解决问题的办法,所以决定从最简单、也相当富有代表性的阻塞套接字开始研究,省略掉一些对所涉问题关系不是很大的代码,保留关键部分,如下:
int i_save_size;//尾巴数据长度
char c_save[2000];//保存上次接收的尾巴数据
char c_recv[2000];//数据接收缓冲区
u_long _stdcall thread_recv(void *arg)
{
... ...
while(TRUE)
{
i_eax=::recv(h,c_recv,2000,0);
if(SOCKET_ERROR==i_eax)
{
::closesocket(h); break;
}
data_patition(c_recv,i_eax,c_save,&i_save_size);//分割数据流
}
return 0;
}
假设数据包格式为:4字节包头+不定长包体,那么我们假设一种情况,recv拷贝到长度2000字节的数据,其中包括两个整包(1500字节,498字节),一个残缺包(2字节),这种情况当然需要做一些处理,处理过程如下:
int data_patition(char *c_data,int i_eax,char *c_save,int *p_save_size)
{
int i_rest=i_eax; char *p_rest=c_data; int i_size;