请问各位你们是如何解决粘包问题的?
有人说在包头附带包大小。但是我不清楚如何设置,因为涉及到包大小是int类型然后又要转换成char类型,然后又要跟包内容进行结合形成“包头+包内容”的形式转发出去。
比如我在发送端发送“helloworld”包内容,共10个字节,我就设置包头为10,那么整个包就是"10helloworld"。
我在接收端接收到的包要怎么判断这个包大小是10而不是1呢?我不想设置标识位,有人建议包头固定为2个字节,就是int类型的2个字节,这样可以程序固定读取头2个字节作为包头。2个字节的包头要转换成char类型再传送出去我这里有点不懂。比如说我要传送长度为256的字符串,就是int 256用itoa转成字符串那就是"256"可是占用了3个字节啊,如果我固定读取2个字节,那可是只能读到25啊!?求助啊!

解决方案 »

  1.   

    用比特位存储 数据包长度,这样 两个字节就可以发 2^15次方的长度,应该够去了其实TCP 一个数据包最多只能发1500字节,这是协议规定了的
      

  2.   

    你所谓“粘包”,其实是一个好的特性,使TCP可以充分利用报文,多携带一些数据。
    用流协议,必须自己组包,这是基本常识。如何组包? 当然是根据上层协议。
      

  3.   

    即使你的包大小是不固定的,但是你的包头最好固定。这样就好办了。每次都收到至少包头大小的包再来决定还需要收多少字节。。还有,你可以参考VCKBASE里面的一篇关于粘包问题的文章!
      

  4.   

    这个要学习P.S  vckbase里是说那篇说确实能解决的文章吧。。也米说怎么解决,人家好像得出结论说粘包存在,也可以解决就没了
      

  5.   

    本帖最后由 VisualEleven 于 2010-09-08 17:42:17 编辑
      

  6.   

    typedef struct DataPacket
    {
    char szHead[2];
    USHORT usID;
    char cCmdType;
    USHORT usLength;
    char szData[MAX_DATA_LENG];
    char szCRC[2];
    char szTail[2];
    DataPacket()
    {
    *szHead = 0x00;
    *(szHead +1) = 0x00;
    usID = 0;
    cCmdType = 0x00;
    memset(szData,0,MAX_DATA_LENG);
    *szCRC = 0x00;
    *(szCRC + 1) = 0x00;
    *szTail = 0x00;
    *(szTail + 1) = 0x00;
    }
    }DATAPACKET ,*PDATAPACKET;发送的时候自己封包,接收的时候自己解包。
      

  7.   

    “包长度#包内容”的这段代码不就是了吗? 多注意些就可以了, 如recv和send什么的....
      

  8.   


    typedef struct DataPacket
    {
    char szHead[2];
    USHORT usID;
    char cCmdType;
    USHORT usLength;
    char szData[MAX_DATA_LENG];
    char szCRC[2];
    char szTail[2];
    DataPacket()
    {
    *szHead = 0x00;
    *(szHead +1) = 0x00;
    usID = 0;
    cCmdType = 0x00;
    memset(szData,0,MAX_DATA_LENG);
    *szCRC = 0x00;
    *(szCRC + 1) = 0x00;
    *szTail = 0x00;
    *(szTail + 1) = 0x00;
    }
    }DATAPACKET ,*PDATAPACKET;
    不能直接发送这个结构体,要封包处理
      

  9.   

    typedef struct _data_packet {
       int packetlen;
       char databuf[1];
    }data_packet, *pdata_packet;//server
        strcpy(message,"X=1366");
        length=strlen(message) + sizeof(data_packet);
        pdata_packet sdata = (pdata_packet)malloc(length);
        sdata->packetlen = length;
        strcpy(sdata->packetlen, message);
        if (send(*m_socket,sdata,length,0)==SOCKET_ERROR )
        {
            AfxMessageBox("无法发送屏幕分辨率数据");
            return 0;
        }
    //client
    pdata_packet rdata;
    int ret,packetlen, readlen = 0;
    ret = recv(m_socket,&packetlen,4,0);
    if(ret != SOCKET_ERROR) {
        rdata = (pdata_packet)malloc(packetlen);
        rdata->packetlen = packetlen;
        readlen += ret;
        while(readlen <= packetlen) {
            ret = recv(m_socket, (char *)rdata + readlen, packlen - readlen, 0);
            if(ret != SOCKET_ERROR)readlen += ret;
            else {
                AfxMessageBox("接收错误");
                closesocket(m_socket);
                return false;
            }
        }
    }
      

  10.   

    TCP 协议里本身就不需要理会包的概念,包是像IP/UDP这类协议里才有的概念TCP里的数据是stream(流),建议楼主可以看看《unix 网络编程》,对在windows下的开发一样有用