BeginReceive 与endReceive 必须成对出现,如果BeginReceive没有及时调用endReceive,可能会出现数据被从buffer中读取二次,如果在下面这行代码下面加入别的代码

就会出现被处理二次的结果 如下

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();处理缓存数据方法

然后再执行

 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还是一般的异步委托方法。

Socket通信中的 BeginReceive与EndReceive的更多相关文章

  1. 【Java TCP/IP Socket】TCP Socket通信中由read返回值造成的的死锁问题(含代码)(转)

    书上示例 在第一章<基本套接字>中,作者给出了一个TCP Socket通信的例子——反馈服务器,即服务器端直接把从客户端接收到的数据原原本本地反馈回去. 书上客户端代码如下: 1 2 3 ...

  2. Socket通信中AF_INET 和 AF_UNIX域的区别

    转载:http://blog.csdn.net/sandware/article/details/40923491 1.  AF_INET域socket通信过程 典型的TCP/IP四层模型的通信过程. ...

  3. socket通信中select函数的使用和解释

    select函数的作用: select()在SOCKET编程中还是比较重要的,可是对于初学SOCKET的人来说都不太爱用select()写程序,他们只是习惯写诸如 conncet().accept() ...

  4. epoll在socket通信中的应用

    当服务器需要服务多个客户时,需要使用并发通信,实现并发通信有以下几种方法: 1.在服务器中fork子进程来为每个客户服务  具体可参考http://www.cnblogs.com/ggjucheng/ ...

  5. [转]SOCKET通信中TCP、UDP数据包大小的确定

    TCP.UDP数据包大小的确定 UDP和TCP协议利用端口号实现多项应用同时发送和接收数据.数据通过源端口发送出去,通过目标端口接收.有的网络应用只能使用预留或注册的静态端口:而另外一些网络应用则可以 ...

  6. IO创建Socket通信中慎用BufferReader中的readLine()

    在编写Socket的Demo的时候,在Server中使用BufferReader获取从客服端发送过来的内容 package cn.lonecloud.socket; import cn.loneclo ...

  7. .net平台下C#socket通信(中)

    上篇.net平台下C#socket通信(上)介绍了socket通信的基本原理及最基本的通信方式.本文在此基础上就socket通信时经常遇到的问题做一个简单总结,都是项目中的一些小问题,拿来此处便于下次 ...

  8. Android中Socket通信之TCP与UDP传输原理

    一.Socket通信简介 Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是"请求-响应方式",即在请求时 ...

  9. .net平台下C#socket通信(转)

    上篇.net平台下C#socket通信(上)介绍了socket通信的基本原理及最基本的通信方式.本文在此基础上就socket通信时经常遇到的问题做一个简单总结,都是项目中的一些小问题,拿来此处便于下次 ...

随机推荐

  1. 谷歌安装器扫描时提示“需要root权限”,不用root也可以的!

    能FQ的用户会用谷歌服务,一般的新手机没有安装谷歌框架,但是在用谷歌安装器安装谷歌市场时会提示"需要root权限",我用的是360手机,按照下面的教程搞好了: 安装完GSM包就可以 ...

  2. stat命令

  3. Selenium基础知识

    本人博客文章网址:https://www.peretang.com/basic-knowledge-of-selenium/ 什么是Selenium Selenium是一个自动化测试工具 是一组不同的 ...

  4. 开发Activity步骤

    第一步:写一个累继承Activity第二步:重写onCreate方法第三步:在主配置文件中注册activity <activity android:name=".类名" an ...

  5. windows embedded compact 2013 正版免费下载

    不知道wince2013是不是真的免费了,不过可以试一下! 下载地址:http://www.microsoft.com/en-us/download/details.aspx?id=39268 你仍然 ...

  6. GithubPages + Hexo + Disqus博客教程

    文章主要描述了利用github page,hexo静态博客框架以及disqus来搭建个人静态博客的详细步骤. github page用来搭建博客的主页,hexo用来更改博客主题.发布文章等等,并通过配 ...

  7. 第2章 系统用户/组管理(2) su和sudo

    本文目录: 2.1 su 2.2 sudo 2.2.1 /etc/sudoers文件 2.2.2 sudo和sudoedit命令 2.1 su 切换用户或以指定用户运行命令. 使用su可以指定运行命令 ...

  8. .NET 开发环境搭建

    概述 在接下来的时间里,将会入手ASP.NET MVC这一专题,尽量用最快的时间,最有效的方法,分别从深度和广度上剖析这一专题,力求讲明白.讲透.以此来与大家分享,力求达到共同学习,共同交流,共同进步 ...

  9. 将数据库从服务器移到浏览器--indexedDB基本操作封装

    数据库是属于服务器的,这是天经地义的事,但是有时候数据也许并非需要存储在服务器,但是这些数据也是一条一条的记录,怎么办?今天来带领你领略一下H5的一个新特性--indexedDB的风骚.你会情不自禁的 ...

  10. Linux 特殊用户权限 suid,sgid, sticky

    每个进程会维护有如下6个ID: 真实身份 : real UID, readl GID --> 登录 shell 使用的身份 有效身份 : effective UID, effective GID ...