看了下以前做socket通信写的代码,发现没有考虑到"粘包"问题.我觉得解决这个问题无非两点:1.定义一个两端通信的信令结构;2.应用层每次能从传输层缓存中拆分出这个结构.下面是部分代码,不对的地方还请各位高手指正!#define MAX_DATA_LEN                   1024   // 信令中数据区长度
#define MAX_PARAMS_LEN                 16     // 无符号字节参数区长度
#define MAX_BUF_LEN                    2048   // 应用层接收/发送缓存区大小// 信令格式
struct _tagPACK_DATA
{
#define PACK_DATA_LEN    sizeof _tagPACK_DATA  // 信令总长度
char     csignal;                      // 信令操作码
int      iparam;                       // 整型参数
char     cparams[MAX_PARAMS_LEN];      // 字节型参数
char     cdata[MAX_DATA_LEN];          // 数据区
};// 接收/发送缓存结构
struct _tagDATA_BUF
{
#define DATA_BUF_LEN     sizeof _tagDATA_BUF   // 缓存总大小
char     cbuf[MAX_BUF_LEN];            // 缓存区
int      isize;                        // 已发送字节数
};...
while(TRUE)
{
DWORD dwEvent = WSAWaitForMultipleEvents(...);  // 等待传输层绑定的事件对象
...
BUF.isize += recv( sock, BUF.cbuf + BUF.isize, PACK_DATA_LEN - BUF.isize, 0 );  // 从远程套接字的接收缓存"剥离"指定大小的数据
if( BUF.isize < PACK_DATA_LEN ) continue;       // 如果接收的数据大小小于信令长度,则等待客户端发送此信令剩余部分的数据,当然这
memcpy( &PACK, BUF.cbuf, PACK_DATA_LEN );       // 些数据是和下一个信令"粘"在一起的.装配完一个信令后,将其拷贝到信令结构.
...
}
...

解决方案 »

  1.   

    你的程序没有问题,但粘包问题肯定存在,因为不能客户端每次发送的的包都是2048个字节我一般是这么处理的,仅供参考typedef struct _tagPACK_DATA
    {
        UINT packLen;
        char buf[1];
    }PACK_DATA,*PPACK_DATA;typedef struct _SIGNAL
    {
        char     csignal;                      // 信令操作码
        int      iparam;                       // 整型参数
        char     cparams[MAX_PARAMS_LEN];      // 字节型参数
        char     cdata[1];                     // 数据区
    }SIGNAL,*PSIGNAL;
    UINT readLen=0,totalRead=0,totalLen=0;
    PPACK_DATA pdata;
    while(TRUE)
    {
    DWORD dwEvent = WSAWaitForMultipleEvents(...);  // 等待传输层绑定的事件对象
    ...
    if(totalRead==0)
    {
         readLen=recv(sock,(char *)&totalLen,4,0);//首先接收字本次包的大小;
         totalRead+=readlen;
         pdata=(PPACK_DATA)malloc(totalLen);
         pdata->packLen=totalLen;
    }
    else
    {
         readLen=recv(sock,(char *)(pdata+totalRead,totalLen-totalRead,0);
         totalRead+=readLen;
         if(totalRead>=totalLen)
         {
             PSIGNAL ps=(PSIGNAL)pdata->buf;
             //处理你的数据
            readLen=totalRead=TotalLen=0;
         }
    }
    ...
    }
      

  2.   

    又是粘包的问题,一年回答12次,都懒得回答了,你去翻翻已解决问题列表,肯定能找到。
    唉,怪不得csdn人气越来越差,翻来覆去总是那几个问题。