BeginReceive执行异步接受数据的判断问题

CAOKAI2010 2011-03-31 01:53:37
BeginReceive主要使用异步接收,一般都是Socket.BeginReceive(buffer, 0, 1024, 0,new AsyncCallback(Read_Callback), Socket);
由于需要指定接收数据的大小,如这里的1024字节,但在连续接收数据时,如果对方每次发送的一帧数据是1536字节,那么本地第一次将接收第一帧的1024个字节,第二次将接收第一帧的512字节和第二帧的512字节,第三次接收第二帧的1024个字节数据。
那么如何对第一帧数据和第二帧数据进行区分呢!特别是每次发送过来一帧数据长度不确定的话,就感觉更难区分了!
请问大家是怎么处理的呢?有没向UDPCLIENT.BEGINRECEIVE那样,不需要给定接收区长度,不需要自己去判断每一帧的?
...全文
456 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
CAOKAI2010 2011-04-01
  • 打赏
  • 举报
回复
书上没的介绍哟,麻烦大家帮帮我啊!
CAOKAI2010 2011-03-31
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 cc_net 的回复:]
看看WINDOWS网络编程前几章
[/Quote]
有电子文档方便传给我一下,好好学习下,谢谢!
cc_net 2011-03-31
  • 打赏
  • 举报
回复
看看WINDOWS网络编程前几章
CAOKAI2010 2011-03-31
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 cc_net 的回复:]
你用Begin开头,必须要区分开来的。比如MSN有2种协议方式

1. 命令 序号 内容\r\n 他是用\r\n结尾,这样你判断一条语句就通过结尾\r\n来区分
2 命令 序号 长度\r\n <负载内容> 这个是传输大量数据用的,先通过\r\n获得主要的头,在从头中获得长度,接着取后面数据。

然后你定义的命令是自己设计的,可以不出现\r\n,内容中的\r\n你可以自己转义。具体协议格式……
[/Quote]
TCP协议保证接收是按顺序的接收的?不会出现这样的情况吗:我用SOCKET.BEGINSEND连续发3个1024字节的数据,第3个1024字节的数据比第2个1024字节的数据先到远端计算机?
CAOKAI2010 2011-03-31
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 sp1234 的回复:]
如果你的设计中有所谓“BEGIN”这类东西,那么扫描解析就是去匹配消息的前5个字节是不是它。如果不是,或者由服务器端关闭远程客户端的连接,或者忽略多个字符直到找到下一次出现5个字节是BEGIN的地方作为下一个消息的头。找到消息这个前缀之后,就按照之后的长度直接取出随后的内容信息(从而也就不会跟内容中的BEGIN混淆)。当然,当读取到的内容字节数不够长度的时候,应该继续等待。

不过现在的电脑运……
[/Quote]
这个和电脑运行快慢有关系?能详细解释下吗?您在传输数据时是怎么对接受到的数据进行的判断的呢!?
  • 打赏
  • 举报
回复
如果你的设计中有所谓“BEGIN”这类东西,那么扫描解析就是去匹配消息的前5个字节是不是它。如果不是,或者由服务器端关闭远程客户端的连接,或者忽略多个字符直到找到下一次出现5个字节是BEGIN的地方作为下一个消息的头。找到消息这个前缀之后,就按照之后的长度直接取出随后的内容信息(从而也就不会跟内容中的BEGIN混淆)。当然,当读取到的内容字节数不够长度的时候,应该继续等待。

不过现在的电脑运行很快,根本没有必要使用什么“BEGIN+长度+内容”这类所谓协议设计方法。
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 caokai2010 的回复:]

出错是指如果DATA中也有我用于判断数据头的数据,比如我使用"BEGIN"作为数据的头,每次发送的数据DATA都加上字节的长度,再加上这个"BEGIN"才发出去。我接受是肯定需要判断数据,如果扫描到"BEGIN"就表示新数据来了,但是如果DATA中也有"BEGIN"那么自然也就容易造成错误的判断了。
[/Quote]
这谈不上出错。因为你只是验证一个消息的前5个字节是“BEGIN”,自然不会跟后边的混淆。

当然,其实用不着去搞这个前缀。例如JSON协议的消息就是没有换行和回车的,所以你就可以用换行或者回车作为每个JSON消息的结束,而用不着前缀和长度之类的信息。
CAOKAI2010 2011-03-31
  • 打赏
  • 举报
回复
出错是指如果DATA中也有我用于判断数据头的数据,比如我使用"BEGIN"作为数据的头,每次发送的数据DATA都加上字节的长度,再加上这个"BEGIN"才发出去。我接受是肯定需要判断数据,如果扫描到"BEGIN"就表示新数据来了,但是如果DATA中也有"BEGIN"那么自然也就容易造成错误的判断了。

http://msdn.microsoft.com/zh-cn/library/dxkwh6zw.aspx
中的例子是在循环接受数据,但是在INTERNET中,会存在后发的数据比先发的数据先到远端的情况,我这里就暂叫帧吧(专业术语知道话麻烦告知下),这样就会出现我上面描述的错误取到第三帧数据的情况!
cc_net 2011-03-31
  • 打赏
  • 举报
回复
你用Begin开头,必须要区分开来的。比如MSN有2种协议方式

1. 命令 序号 内容\r\n 他是用\r\n结尾,这样你判断一条语句就通过结尾\r\n来区分
2 命令 序号 长度\r\n <负载内容> 这个是传输大量数据用的,先通过\r\n获得主要的头,在从头中获得长度,接着取后面数据。

然后你定义的命令是自己设计的,可以不出现\r\n,内容中的\r\n你可以自己转义。具体协议格式当然是自己根据情况决定了。

对于异步你理解不对。TCP保证可靠的、顺序的(数据包以发送的顺序接收)以及不会重复的数据传输。
  • 打赏
  • 举报
回复
比如说看看msdn:http://msdn.microsoft.com/zh-cn/library/dxkwh6zw.aspx
的demo代码。明明是在一个Read_Callback方法中才去异步读取下一块数据(执行s.BeginReceive),不可能“第三帧比第二帧先到”。
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 caokai2010 的回复:]
我也想在数据帧前加上“BEGIN”+长度+DATA的方法,但有2个困扰问题:
1、如果DATA中有“BEGIN”会导致判断头字节出错,这该如何是好!?
2、因为是异步的,如上所述,如果我第三帧的数据比第二帧的先到,就会导致我从第一帧取了1024个字节,从第三帧取512字节的错误组合!
[/Quote]

1. 不懂你的“出错”是什么意思。

2. 异步Receive不是你说的第三帧比第二帧先到(且不管这里的“帧”这个词是否合适)。异步Receive,也是顺序读取数据的。你不妨实际去看看异步Receive的代码。
CAOKAI2010 2011-03-31
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 cc_net 的回复:]
你用socket肯定有自己的数据协议,比如一条数据以什么结尾。或则说头上代上数据长度比如 MSG 200 内容。

收到后更具协议去判断数据是否完整。
[/Quote]
我也想在数据帧前加上“BEGIN”+长度+DATA的方法,但有2个困扰问题:
1、如果DATA中有“BEGIN”会导致判断头字节出错,这该如何是好!?
2、因为是异步的,如上所述,如果我第三帧的数据比第二帧的先到,就会导致我从第一帧取了1024个字节,从第三帧取512字节的错误组合!
cc_net 2011-03-31
  • 打赏
  • 举报
回复
你用socket肯定有自己的数据协议,比如一条数据以什么结尾。或则说头上代上数据长度比如 MSG 200 内容。

收到后更具协议去判断数据是否完整。

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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