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

Socket通信中的 BeginReceive与EndReceive,码迷,mamicode.com

时间: 2024-10-14 02:29:07

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

Socket通信中AF_INET 和 AF_UNIX域的区别

转载:http://blog.csdn.net/sandware/article/details/40923491 1.  AF_INET域socket通信过程 典型的TCP/IP四层模型的通信过程. 发送方.接收方依赖IP:Port来标识,即将本地的socket绑定到对应的IP端口上,发送数据时,指定对方的IP端口,经过Internet,可以根据此IP端口最终找到接收方:接收数据时,可以从数据包中获取到发送方的IP端口. 发送方通过系统调用send()将原始数据发送到操作系统内核缓冲区中.内核

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

书上示例 在第一章<基本套接字>中,作者给出了一个TCP Socket通信的例子——反馈服务器,即服务器端直接把从客户端接收到的数据原原本本地反馈回去. 书上客户端代码如下: import java.net.Socket; import java.net.SocketException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class TCPEch

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

select函数的作用: select()在SOCKET编程中还是比较重要的,可是对于初学SOCKET的人来说都不太爱用select()写程序,他们只是习惯写诸如 conncet().accept().recv()或recvfrom这样的阻塞程序(所谓阻塞方式block,顾名思义,就是进程或是线程执行到这些函数时必须等待某个事件发生,如果事件没有发生,进程或线程就被阻塞,函数不能立即返回).可是使用select()就可以完成非阻塞(所谓非阻塞方式non-block,就是进程或线程执行此函数时不必

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

本文主要讲述: 1.正常通信中握手建立 2.一对多的通信 3.发送接收数据格式转换 4.资源释放 5.开启并保持服务监听 1.握手建立正常的通信通道 项目需要通信的双方(假设是一个上位机.一个下位机)之间需要建立一个稳定的通道,以便进行通信.本项目中具体操作是:上位机作为服务器,下位机作为客户端,同时制定通信协议.上位机首先打开监听等待建立通道,下位机主动连接上位机后发送连接成功的信息到上位机,上位机根据通信协议发送数据到下位机,此时通道已经建立.但为了保险起见(同时遵循三次握手),客户端再次发

Android开发笔记(一百一十一)聊天室中的Socket通信

Socket通信 基本概念 对于程序开发来说,网络通信的基础就是Socket,但因为是基础,所以用起来不容易,今天我们就来谈谈Socket通信.计算机网络有个大名鼎鼎的TCP/IP协议,普通用户在电脑上设置本地连接的ip时,便经常看到下图的弹窗,注意红框部分已经很好地描述了TCP/IP协议的作用. TCP/IP是个协议组,它分为三个层次:网络层.传输层和应用层: 网络层包括:IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协议. 传输层包括:TCP协议.UDP协议. 应用层包括:HT

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

上篇.net平台下C#socket通信(上)介绍了socket通信的基本原理及最基本的通信方式.本文在此基础上就socket通信时经常遇到的问题做一个简单总结,都是项目中的一些小问题,拿来此处便于下次使用,同时对在使用socket时出现些许问题的同仁们多一个粗浅建议.不足之处请提出,谢谢. 本文主要讲述: 1.正常通信中握手建立 2.一对多的通信 3.发送接收数据格式转换 4.资源释放 5.开启并保持服务监听 1.握手建立正常的通信通道 项目需要通信的双方(假设是一个上位机.一个下位机)之间需要

Java系列讲座一:TCP方式Socket通信案例讲解

开发网络通信软件,如QQ,阿里旺旺等即时通讯软件时,Socket通信是必备的基础知识,今天跟大家谈谈Socket通信中TCP方式通信的软件开发步骤及主要代码讲解: 第一步:开发服务器端程序Server.java,源代码如下: package T16; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; imp

java Socket通信使用BufferedReader和BufferedWriter的注意事项

注意事项:readLine()要求有换行标识,write()要输出换行标识,要调用flush()刷新缓冲区. 以下是取自java socket通信中的一小段代码. BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.get

Android网络编程之Socket通信

Socket(套接字)是一种通信机制,可以实现单机或跨网络进行通信,其创建需要明确的区分C(客户端)/S(服务器端),支持多个客户端连接到同一个服务器.有两种传输模式: 1).面向连接的传输:基于TCP协议,可靠性高,但效率低: 2).面向无连接的传输:基于UDP协议,可靠性低,但效率高: Android中,直接采用Socket通信应该是我们遇到的最低级的网络运用.尽管已经作了很大程度的抽象,但是纯粹的Socket通信,仍然给开发者留下很多细节需要处理,尤其在服务器端,开发者需要处理多线程以及数