Socket 收发内部拆包封包函数
在socket通信的时候,有时候数据比较大,内部缓存会溢出,导致发送或接收数据不正确。
针对这个情况,封装了一个接收和发送的底层函数,根据缓存大小批次发送和接收,内部有自己的缓冲区,测试情况良好。
//发送函数
const int SEND_BUFFER_LEN =1024;//发送缓冲区大小
int Send_package_Data(const SOCKET mysocket, const uint32_t ui32Length, const char * pvalue)
{
uint32_t irecv=0;
int ipos=0;
if (ui32Length<= SEND_BUFFER_LEN)//小于1024发一包数据
{
char Buffer_one[SEND_BUFFER_LEN+1]={0};发送缓冲区
memset(Buffer_one,0,sizeof(Buffer_one));
memcpy(Buffer_one,pvalue,ui32Length);
irecv=0;
uint32_t pos1 = 0;//下一次发送需要开始的位置
while(pos1 < ui32Length)
{
irecv = send(mysocket, Buffer_one+pos1, ui32Length-pos1, 0);
if(irecv <=0) //错误
{
printf("Send failed: %s\r\n", strerror(errno));
break;
}
pos1 += irecv;
}
return irecv;
}
else//大于1024发多包数据
{
const uint32 ics=ui32Length / SEND_BUFFER_LEN;
const uint32 imod=ui32Length % SEND_BUFFER_LEN;
printf("ics = %d\r\n",ics);
printf("imod = %d\r\n",imod);
for (uint32 i = 0; i < ics; i++)
{
ipos=SEND_BUFFER_LEN*i;
char Buffer_cs[SEND_BUFFER_LEN+1]={0};发送缓冲区
memset(Buffer_cs,0,sizeof(Buffer_cs));
memcpy(Buffer_cs,pvalue+ipos,SEND_BUFFER_LEN);
irecv=0;
uint32_t pos2 = 0;//下一次发送需要开始的位置
while(pos2 < SEND_BUFFER_LEN)
{
irecv = send(mysocket, Buffer_cs+pos2, SEND_BUFFER_LEN-pos2, 0);
if(irecv <=0) //错误
{
printf("Send failed: %s\r\n", strerror(errno));
break;
}
pos2 += irecv;
}
}
if (irecv <= 0)
{
return irecv;
}
if (imod>0)
{
ipos=SEND_BUFFER_LEN*ics;
char Buffer_mod[SEND_BUFFER_LEN+1]={0};发送缓冲区
memset(Buffer_mod,0,sizeof(Buffer_mod));
memcpy(Buffer_mod,pvalue+ipos,imod);
printf("Buffer_mod: %s\r\n", Buffer_mod);
irecv=0;
uint32_t pos3 = 0;//下一次发送需要开始的位置
while(pos3 < imod)
{
irecv = send(mysocket, Buffer_mod+pos3, imod-pos3, 0);
if(irecv <=0) //错误
{
printf("Send failed: %s\r\n", strerror(errno));
break;
}
pos3 += irecv;
}
}
return irecv;
}
return 0;
}
//接收函数
const int RECV_BUFFER_LEN =1024;//发送缓冲区大小
int Recv_package_Data(const SOCKET mysocket, uint32_t ui32Length, char * pvalueData)
{
if (ui32Length<=0) return -200;
//清空缓冲区
memset(pvalueData,0,ui32Length);
uint32_t irecv=0;
int ipos=0;
if (ui32Length<= RECV_BUFFER_LEN)//小于1024收一包数据
{
char Buffer_one[RECV_BUFFER_LEN+1]={0};接收缓冲区
uint32_t pos1 = 0;//下一次发送需要开始的位置
irecv=0;
while(pos1 < ui32Length)
{
irecv = recv(mysocket, Buffer_one+pos1, ui32Length-pos1, 0);
if(irecv <=0) //错误
{
printf("Recv_klv_value::Buffer_one::recv failed: %s\r\n", strerror(errno));
break;
}
pos1 += irecv;
}
if (irecv>0)
{
memcpy(pvalueData,Buffer_one,ui32Length);
}
return irecv;
}
else//大于1024多包接收数据
{
const uint32 ics=ui32Length / RECV_BUFFER_LEN;
const uint32 imod=ui32Length % RECV_BUFFER_LEN;
printf("ics = %d\r\n",ics);
printf("imod = %d\r\n",imod);
for (uint32 i = 0; i < ics; i++)
{
ipos=RECV_BUFFER_LEN*i;
char Buffer_cs[RECV_BUFFER_LEN+1]={0};接收缓冲区
irecv=0;
uint32_t pos2 = 0;//下一次发送需要开始的位置
while(pos2 < RECV_BUFFER_LEN)
{
irecv = recv(mysocket, Buffer_cs+pos2, RECV_BUFFER_LEN-pos2, 0);
if(irecv <=0) //错误
{
printf("Recv_klv_value::Buffer_one::recv failed: %s\r\n", strerror(errno));
break;
}
pos2 += irecv;
}
if (irecv>0)
{
memcpy(pvalueData+ipos,Buffer_cs,RECV_BUFFER_LEN);
}
}
if (irecv <= 0)
{
return irecv;
}
if (imod>0)
{
ipos=RECV_BUFFER_LEN*ics;
char Buffer_mod[RECV_BUFFER_LEN+1]={0};接收缓冲区
uint32_t pos3 = 0;//下一次发送需要开始的位置
irecv=0;
while(pos3 < imod)
{
irecv = recv(mysocket, Buffer_mod+pos3, imod-pos3, 0);
if(irecv <=0) //错误
{
printf("Recv_klv_value::Buffer_mod::recv failed: %s\r\n", strerror(errno));
break;
}
pos3 += irecv;
}
if (irecv > 0)
{
memcpy(pvalueData+ipos,Buffer_mod,imod);
}
}
return irecv;
}
return 0;
recv函数的返回值解析如下:
如果成功接收数据,则返回接收到的字节数。
如果连接已关闭,则返回0。
如果发生错误,则返回-1,并可以通过errno变量获取具体的错误信息。
}