局域网UDP传输,数据包不定长的问题? 本帖最后由 VisualEleven 于 2012-06-01 08:00:42 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 这个buf一般会定义为最大的UPD发送包大小. 假如你有任何一个地方会存在 send(buf, 64K, ...)的话, 那么相应的recv就必须定义一个64K大小的buf来接收数据. 这个是按最大包大小来定的. UDP包头中是带有本次包的长度的,楼主在接收的时候可以先判断此次接收包的长度,然后再使用while()循环接收,直到长度接收够 #3楼 得分:0回复于:2012-05-29 09:39:47UDP包头中是带有本次包的长度的,楼主在接收的时候可以先判断此次接收包的长度,然后再使用while()循环接收,直到长度接收够 健议使用UDX可靠传输协议,可联系我。 如何获得数据包的长度呢?有没有什么事件可以响应?还是必须在子线程中用while轮询?客户端程序如何知道有数据包到达?while(recvfrom()>0){ ReadToBuf();} 这就要涉及流化,如同TCP,如果你流化成功后,你可以获取任意长度的数据。比如,四字节的长度。但是流化后,就会存在粘包问题。你要解决的是灵活的分包,合并包的机制,才能流化,从而可以取得任意思长度,比如1字节,或四字节的长度,从而可以得到所有你想要的数据。UDX协议是一套我开发了5,6年的UDP可靠协议,支持流化,流式,包式方式工作,让开发人员,对这些细节不用关心,效率高,丢包少。你可以和我一起交流,一起进步,共同提高,UDX的网址www.goodudx.com你的问题要从你最基本实现开始。 你命令为什么要非定长啊。而且这么长的命令。你应该加包头 + 序列号+长度因为你是UDP sock.Recvie(buf,num_bytes,SOCK_DGRM); 这个sock是什么对象?我的感觉是这个函数调用应该有返回值这个返回要么是错误代码要么就是实际接收字节 UDP不用while来接收,一次接收即可,返回的就是长度,至于预先缓存区可以申请个大点的缓冲区来接收UDP报文也不会很大的 你的包设计没有问题,你已经说了,一个数据包=包头+数据包头包含了一些基本信息,如包类型是命令还是数据,包总数,当前包编号等等。如果你想知道该读取多少信息,在包头中保存后面数据部分的长度,同时包头写成一个定长结构体,你读取一个包的时候,先把读取定长的包头信息,再根据包头里面的长度len信息来读取len字节的数据,就是后面的数据部分的长度。如果你包的设计是不定长的,包头应该是一个共用结构体,读取时,分两步,struct Header{ char msg_type; //包类型 命令或者数据 int total; //总包数 int curr; //当前包数 int len; //数据部分的长度};1、recv(socket,buf,sizeof(struct Header)); //读取包头,已获取基本控制信息 struct Header h; memcpy(&h,buf,sizeof(h));2、recv(socket,buf,h.len); //读取数据部分 if ( h.msg_type == XX ) { } else { } 你要明白UDP TCP的区别你用UDP发一包就是一包.要么收到,要么收不到一个完整的包.不能超过路由长度.如果你要分很多小包一个UDP一个的发.你得自己定义协议.序列号+长度+内容+是否有后序标志 +检验证 UDP可以不必给包头定义长度,不过UDP包有长度限制,查看UDP包协议可以发现,IP数据包最大长度65535,除去20字节的IP首部,和8字节的UDP首部,剩下的就是最大长度。 申请一个大的buf,一次接收完全。 为什么在状态条上无法显示时间? 现在应该用vc6还是vs2008? Splitter控件相关:对准分割线点以下鼠标,分割线便会移动,如何阻止这种情况的发生。 PostMessage的消息被发送多次 WIN32 APP中怎么在1024*768,和800*600中切换? 再请教一些关于位图设置问题 请高手指教如何实现网络流量的监听程序,是采用了什么样的原理? 大家用什么安装制作工具,那个好呢? 在2k操作系统下,怎么看系统的显卡,就是在运行那个地方输入什么命令! vc高手在哪里?没有吗?还是我的问题太难呢? IOCP中AcceptEx只连接不发送数据问题? IOCP服务器目前感觉遇到二个瓶颈?
如何获得数据包的长度呢?有没有什么事件可以响应?还是必须在子线程中用while轮询?客户端程序如何知道有数据包到达?
while(recvfrom()>0)
{
ReadToBuf();
}
你应该加包头 + 序列号+长度
因为你是UDP
这个sock是什么对象?
我的感觉是
这个函数调用应该有返回值
这个返回要么是错误代码
要么就是实际接收字节
UDP报文也不会很大的
包头包含了一些基本信息,如包类型是命令还是数据,包总数,当前包编号等等。如果你想知道该读取多少信息,在包头中保存后面数据部分的长度,同时包头写成一个定长结构体,你读取一个包的时候,先把读取定长的包头信息,再根据包头里面的长度len信息来读取len字节的数据,就是后面的数据部分的长度。
如果你包的设计是不定长的,包头应该是一个共用结构体,读取时,分两步,
struct Header
{
char msg_type; //包类型 命令或者数据
int total; //总包数
int curr; //当前包数
int len; //数据部分的长度
};
1、recv(socket,buf,sizeof(struct Header)); //读取包头,已获取基本控制信息
struct Header h;
memcpy(&h,buf,sizeof(h));2、recv(socket,buf,h.len); //读取数据部分 if ( h.msg_type == XX )
{
}
else
{
}