局域网UDP传输,数据包不定长的问题?

Cacar 2012-05-28 02:15:15
对方发给我的包分两种类型,一种是命令,一种是数据,二者的长度是不同的,命令只有一个数据包(<1000字节,长度不定),数据可能分多个包。现在只是在发送的时候在头部加了标记,来区分命令和数据(如果是数据,头部还包含了总包数/当前包序号)~

问题是:在接收线程中,如何知道应该接收多少个字节?即不知道来的是命令还是数据,

while(true)
{
sock.Recvie(buf,num_bytes,SOCK_DGRM); // 怎么知道这里num_bytes该接多少呢?正在处理的时候,来新包怎办?
// 判断头,根据类型取出对应数据,再做其他处理...
}


没怎么接触过,求指点~思路、链接、代码片段~
...全文
808 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
Eleven 2012-06-30
  • 打赏
  • 举报
回复
申请一个大的buf,一次接收完全。
yitang2003 2012-06-30
  • 打赏
  • 举报
回复
增加应用层解包过程
nanchangfantasy 2012-06-29
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]
UDP不用while来接收,一次接收即可,返回的就是长度,至于预先缓存区可以申请个大点的缓冲区来接收
UDP报文也不会很大的
[/Quote]
UDP可以不必给包头定义长度,不过UDP包有长度限制,查看UDP包协议可以发现,IP数据包最大长度65535,除去20字节的IP首部,和8字节的UDP首部,剩下的就是最大长度。
wapjia43106140 2012-06-28
  • 打赏
  • 举报
回复
你要明白UDP TCP的区别

你用UDP发一包就是一包.要么收到,要么收不到一个完整的包.不能超过路由长度.

如果你要分很多小包一个UDP一个的发.

你得自己定义协议.序列号+长度+内容+是否有后序标志 +检验证
yby4769250 2012-06-26
  • 打赏
  • 举报
回复
你的包设计没有问题,你已经说了,一个数据包=包头+数据
包头包含了一些基本信息,如包类型是命令还是数据,包总数,当前包编号等等。如果你想知道该读取多少信息,在包头中保存后面数据部分的长度,同时包头写成一个定长结构体,你读取一个包的时候,先把读取定长的包头信息,再根据包头里面的长度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
{
}
hurryboylqs 2012-06-25
  • 打赏
  • 举报
回复
UDP不用while来接收,一次接收即可,返回的就是长度,至于预先缓存区可以申请个大点的缓冲区来接收
UDP报文也不会很大的
quwei197874 2012-06-25
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]
UDP包头中是带有本次包的长度的,楼主在接收的时候可以先判断此次接收包的长度,然后再使用while()循环接收,直到长度接收够
[/Quote]++
danscort2000 2012-06-25
  • 打赏
  • 举报
回复
sock.Recvie(buf,num_bytes,SOCK_DGRM);
这个sock是什么对象?
我的感觉是
这个函数调用应该有返回值
这个返回要么是错误代码
要么就是实际接收字节
judgment823 2012-06-25
  • 打赏
  • 举报
回复
你可以在包头注明长度啊
wapjia43106140 2012-06-21
  • 打赏
  • 举报
回复
你命令为什么要非定长啊。而且这么长的命令。
你应该加包头 + 序列号+长度
因为你是UDP
UDX协议 2012-06-14
  • 打赏
  • 举报
回复
这就要涉及流化,如同TCP,如果你流化成功后,你可以获取任意长度的数据。比如,四字节的长度。



但是流化后,就会存在粘包问题。

你要解决的是灵活的分包,合并包的机制,才能流化,从而可以取得任意思长度,比如1字节,或四字节的长度,从而可以得到所有你想要的数据。

UDX协议是一套我开发了5,6年的UDP可靠协议,支持流化,流式,包式方式工作,让开发人员,对这些细节不用关心,效率高,丢包少。

你可以和我一起交流,一起进步,共同提高,UDX的网址www.goodudx.com

你的问题要从你最基本实现开始。
Cacar 2012-06-14
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

#3楼 得分:0回复于:2012-05-29 09:39:47UDP包头中是带有本次包的长度的,楼主在接收的时候可以先判断此次接收包的长度,然后再使用while()循环接收,直到长度接收够
[/Quote]

如何获得数据包的长度呢?有没有什么事件可以响应?还是必须在子线程中用while轮询?客户端程序如何知道有数据包到达?
while(recvfrom()>0)
{
ReadToBuf();
}
UDX协议 2012-05-29
  • 打赏
  • 举报
回复
健议使用UDX可靠传输协议,可联系我。
wyx100 2012-05-29
  • 打赏
  • 举报
回复
#3楼 得分:0回复于:2012-05-29 09:39:47UDP包头中是带有本次包的长度的,楼主在接收的时候可以先判断此次接收包的长度,然后再使用while()循环接收,直到长度接收够
jiuzhoulh 2012-05-29
  • 打赏
  • 举报
回复
UDP包头中是带有本次包的长度的,楼主在接收的时候可以先判断此次接收包的长度,然后再使用while()循环接收,直到长度接收够
ouyh12345 2012-05-28
  • 打赏
  • 举报
回复
阻塞还是非阻塞?
最好在包头里带上数据长度
dfasri 2012-05-28
  • 打赏
  • 举报
回复
这个buf一般会定义为最大的UPD发送包大小. 假如你有任何一个地方会存在 send(buf, 64K, ...)的话, 那么相应的recv就必须定义一个64K大小的buf来接收数据. 这个是按最大包大小来定的.

18,363

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧