IOCP数据残包断包问题 当要传输的数据量过大或则过频繁时会出现残包断包问题吧,有人说用数据头来标示要传输数据的总大小,具体该怎么操作呢,望高手指点,有代码更好,本人对乱序问题有点理解了,现在又面临这个问题 烦~~新人,的确也没分可以给~ 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 // 以下代码仅供参考voidCPPX_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(); // 读取下一个数据包头 }} 呵呵,简单的来说,就是在每个数据包外面再加一个头结构,比如:struct TCPHEADER{ byte bFlag; // 下面要发送的数据块的大小 DWORD nDataLen;}然后把这个结构把到包的前面。然后再解决粘包的问题http://www.vckbase.com/document/viewdoc/?id=1203 没有所谓的粘包啥的。还是需要了解一点基础的TCP/IP协议的。TCP是面向字节流的传输控制协议,没有消息边界,在SOCKET编程发送的时候,你无法预期每次发送多少,虽然你可以指定request字节数,但是实际的传输字节是底层协议栈控制的。所以你需要根据每次发送多少,来检查是否已经发送完毕,如果没有,继续投递WSASend()异步操作请求发送后续数据。接收同理。接收的时候就牵涉到对对方投递的数据字节流进行恢复,也就是把TCP报文当中自己的货物码流给卸载下来,那么就需要根据一些必要的信息进行重组确定是你的东西,并且够数!SOCKET编程已经封装了IP分段重组,协议栈已经实现了,这个就让SOCKET编程变得简单多了。你只需要定义个货物清单表,先发送给对方,对方收货后照单验收就行了。简单来说就是个长度信息以及类型识别信息就行了,当然这个根据实际需要扩展。 vc2008 lable数据更新的问题 CAsyncSocket的OnAccept究竟是何时触发? 高薪诚聘C++开发人员加盟 如何获得正在写注册表的进程的信息 纯资源dll的问题 关于查询注册表键值出现的问题,总是ERROR_MORE_DATA!? 我的这段代码错在哪儿吗?请高手指教!! 如何获得一个按钮在对话框中的位置?(不是屏幕的上的位置) 怎样把byte转换为char*类型的> 问问。。关于LPCSTR。LPSTR、LPCWSTR、LPWSTR、LPTSTR、LPCTSTR 哪个才是DHCP的服务器地址? 高手请教!怎样自动将文件夹中新的文件上传到FTP
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(); // 读取下一个数据包头
}
}
比如:
struct TCPHEADER
{
byte bFlag;
// 下面要发送的数据块的大小
DWORD nDataLen;
}然后把这个结构把到包的前面。
然后再解决粘包的问题
http://www.vckbase.com/document/viewdoc/?id=1203