首页 > 代码库 > Socket通信中的 BeginReceive与EndReceive
Socket通信中的 BeginReceive与EndReceive
BeginReceive 与endReceive 必须成对出现,如果BeginReceive没有及时调用endReceive,可能会出现数据被从buffer中读取二次,如果在下面这行代码下面加入别的代码
就会出现被处理二次的结果 如下
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public void BeginReceive(SessionListner listner) { if (listner.State != TSessionState.Active) { return ; } try { int bufferOffset = this .BufferManager.GetReceivevBufferOffset(m_bufferBlockIndex); WorkSocket.BeginReceive( this .BufferManager.ReceiveBuffer, bufferOffset, this .BufferManager.ReceiveBufferSize, SocketFlags.None, this .EndReceiveDatagram, listner); listner.Receive(); } catch (Exception err) // 读 Socket 异常,准备关闭该会话 { listner.DisconnectType = TDisconnectType.Exception; listner.State = TSessionState.Inactive; //这个客户状态不活动了 //说明发送端口被异常关闭了 this .OnSessionReceiveException(listner, err); } } |
上面的 listner.Receive();处理缓存数据方法
然后再执行
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | private void EndReceiveDatagram(IAsyncResult iar) { SessionListner listner = (iar.AsyncState as SessionListner); if (listner.State != TSessionState.Active) { return ; } try { int cr = WorkSocket.EndReceive(iar); Console.WriteLine(cr); if (cr == 0) { listner.DisconnectType = TDisconnectType.Normal; listner.State = TSessionState.Inactive; //被关闭了,需要及时关闭 } else { listner.LastSessionTime = DateTime.Now; this .BufferManager.RealReceiveSize = cr; this .BeginReceive(listner); } } |
就出现被二次处理的问题,分析得出:1,在第一次读取完就处理缓冲数据,2同时进入了EndReceiveDatagram方法,再一次时进入BeginReceive方法 ,但没有处理完第一次缓存数据,就可能导致处理数据不正确。
需要改成:EndReceiveDatagram中处理数据
else { listner.LastSessionTime = DateTime.Now; this.BufferManager.RealReceiveSize = cr; listner.Receive(); this.BeginReceive(listner); }
总结:处理数据永远需要放到接收后处理,BeginReceive在永远不断的起线程,而endReceive在不断的帮它完成回收和结束工作。在Begin中下面放执行代码有可能有一定问题。也就是在没有end的时候,没有阻塞后,再操作共享变量有一定问题,所以begin与end同时操作共享对象或变量时时一定要end之后。无论socket还是一般的异步委托方法。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。