当要传输的数据量过大或则过频繁时会出现残包断包问题吧,有人说用数据头来标示要传输数据的总大小,具体该怎么操作呢,望高手指点,有代码更好,本人对乱序问题有点理解了,现在又面临这个问题   烦~~新人,的确也没分可以给~

解决方案 »

  1.   

    // 以下代码仅供参考
    void
    CPPX_Session::read_complete (ACE_Message_Block &mb)
    {
        if( mb.msg_type() == MBT_HEAD ){                                            // 接收到数据包头
            if( mb.space() )                                                        // 数据包头未接收完
                return m_io_ref.read_message(mb,mb.space());                        // 继续接受数据包头,直至超时
            PacketHead_t * head = reinterpret_cast<PacketHead_t *>(mb.rd_ptr());    // 验证包头是否合法
            if( head->proto_version != PROTO_VERSION_ID )                           // 如果包头识别码不正确
                return mb.release(),close(),_post_close_notify();                   // 丢弃非法包头,主动关闭连接
            ACE_Message_Block * data;
            ACE_NEW(data, ACE_Message_Block(head->data_length,MBT_DATA));           // 创建接收包体的消息块
            data->cont(&mb);                                                        // 数据包头挂接在包体后,方便处理完后销毁
            return m_io_ref.read_message(*data,data->space());                      // 开始接受数据包体,直至超时
        }
        if( mb.msg_type() == MBT_DATA ){                                            // 接收到数据包体
            if( mb.space() )                                                        // 数据包体未接收完
                return m_io_ref.read_message(mb,mb.space());                        // 继续接受数据包体,直至超时
            _dispatch_message(mb);                                                  // 包体数据已接收完,分派处理数据包体
            if( m_post_close )                                                      // 会话被主动关闭
                return _post_close_notify();                                        // 通知调度器删除会话
            return _init_read_stream();                                             // 读取下一个数据包头
        }
    }
      

  2.   

    呵呵,简单的来说,就是在每个数据包外面再加一个头结构,
    比如:
    struct TCPHEADER

       byte bFlag;
       // 下面要发送的数据块的大小
       DWORD nDataLen;
    }然后把这个结构把到包的前面。
    然后再解决粘包的问题
    http://www.vckbase.com/document/viewdoc/?id=1203
      

  3.   

    没有所谓的粘包啥的。还是需要了解一点基础的TCP/IP协议的。TCP是面向字节流的传输控制协议,没有消息边界,在SOCKET编程发送的时候,你无法预期每次发送多少,虽然你可以指定request字节数,但是实际的传输字节是底层协议栈控制的。所以你需要根据每次发送多少,来检查是否已经发送完毕,如果没有,继续投递WSASend()异步操作请求发送后续数据。接收同理。接收的时候就牵涉到对对方投递的数据字节流进行恢复,也就是把TCP报文当中自己的货物码流给卸载下来,那么就需要根据一些必要的信息进行重组确定是你的东西,并且够数!SOCKET编程已经封装了IP分段重组,协议栈已经实现了,这个就让SOCKET编程变得简单多了。你只需要定义个货物清单表,先发送给对方,对方收货后照单验收就行了。简单来说就是个长度信息以及类型识别信息就行了,当然这个根据实际需要扩展。