实现基于事件通知的.Net套接字

2016-02-19 12:21 10 1 收藏

下面,图老师小编带您去了解一下实现基于事件通知的.Net套接字,生活就是不断的发现新事物,get新技能~

【 tulaoshi.com - Web开发 】

  以前学过MFC,我用过的它里面的包装Winsock的两个类CSocket和CAsyncSocket,我一直觉得它哪个事件通知的功能比较不错,特别是在连接的两方收发数据没有一定的规律的时候比较有用,虽然不用它的事件通知也可以实现功能,但是你需要循环检测套接字的状态或者阻塞等待,如果每次都要做这些琐碎的工作岂不是很麻烦,于是我就想对这些功能作一次封装。当然在.net里面采用delegate和event是最好的选择了。下面就是我实现的一些细节:

  先讲一下思路:其实这个还是很简单了,估计高手们会不屑一顾了^_^。当套接字开始工作,比如开始监听、开始连接的时候,启动一个线程不停的检测套接字的状态,当某一事件的状态条件满足时就触发此事件,要知道具体检测套接字状态的方法,请往下看。

  平常用套接字编成的时候可能需要用到的功能就是:连接成功或者失败的通知、在监听的套接字上有挂起的连接的通知、有数据可以接受的通知、套接字关闭的通知、还有套接字空闲可以发送数据的通知等,我也就使对上面几个功能作了封装,不过我觉得最后面一个功能用处不大???

  我的Socket类是从System.Net.Sockets.Socket继承下来的,类名TcpEventSocket,实现如下:

  先申明事件的委托类型,具体看代码

  public delegate void AcceptConnectionHandler();

  public delegate void ConnectCompletedHandler(bool connected); //connected表明连接成功与否

  public delegate void DataCanSendHandler();

  public delegate void DataCanReceiveHandler(int buffersize); //当前可以接受的数据量

  public delegate void SocketClosedHandler();

  这些类型具体什么意思应该能看出来吧,另外还要申明对应的事件

  public event AcceptConnectionHandler AcceptConnection;

  public event ConnectCompletedHandler ConnectCompleted;

  public event DataCanSendHandler DataCanSend;

  public event DataCanReceiveHandler DataCanReceive;

  public event SocketClosedHandler SocketClosed;

  另外加了几个虚方法,这几个方法用来触发事件

  protected virtual void OnAcceptConnection();
  protected virtual void OnConnectCompleted(bool connected)

  protected virtual void OnDataCanSend()
  protected virtual void OnDataCanReceive(int buffersize)

  protected virtual void OnSocketClosed()

  为了在适当的事机启动检测线程,我重写了几个基类的方法:

  new public void Listen(int backlog)

  {

  base.Listen(backlog);

  sockState = SocketState.Listenning;

  if (!checkThread.IsAlive)

  checkThread.Start();

  }

  new public void Connect(EndPoint remoteEP)

  {

  try

  {

  base.Connect(remoteEP);

  this.Blocking = false; //设置非阻塞状态,以便事件通知的效率

  if (!checkThread.IsAlive)

  checkThread.Start();

  }

  catch(SocketException)

  {

  OnConnectCompleted(false);

  }

  }

  这两个方法实际编成中都应该首先被调用的,所以有他们启动检测线程比较合适,另外线程启动了必然也要中止,于是我重写了Close方法

  new public void Close()

  {

  if(checkThread.IsAlive) //先中止线程再关闭连接

  checkThread.Abort();

  base.Close();

  sockState = SocketState.Disconnected;

  OnSocketClosed();

  }

  于是剩下的工作就是怎么检测套接字了,Socket类有个Select的静态方法,它可以检测很多套接字的状态,不过这里只需要检测一个,所以直接用Socket的Poll方法,Poll的具体用法可以看MSDN,我这里用代码说明我对套接字的检测方法

  while(true) //循环检查

  {

  if (sockState == SocketState.Disconnected) //如果当前没有连接

  {

  if (Poll(500, SelectMode.SelectWrite))

  OnConnectCompleted(true); //如果为可写状态,则表示连接成功

  }

  else if(sockState == SocketState.Listenning)

  {

  if (Poll(500, SelectMode.SelectRead)) //如果在监听状态发现套接字有数据可读则表示已经有人连接上来可以调用Accept接受连接

  OnAcceptConnection();

  }

  else //这里sockState = SocketState.Connected

  {

  if (Poll(500, SelectMode.SelectWrite)) //如果有可写状态则表示可以发送数据

  OnDataCanSend();

  if (Poll(500, SelectMode.SelectRead)) //如果有可读状态

  {

  if (Available 0) //如果有数据可读表示可以调用Receive接受数据

  OnDataCanReceive(Available);

  else

  {

  OnSocketClosed(); //没数据可读表示连接已经关闭

  break;

  }

  }

  }

  //如果没有连接并且有错误状态,则连接失败

  if (sockState == SocketState.Disconnected && Poll(500, SelectMode.SelectError))

  OnConnectCompleted(false);

  }

  这里的OnXXX方法就是执行事件通知的方法,并且派生类中可以重载这些方法直接获得事件通知而不需要挂界别的事件通知处理函数(类似于MFC的OnAccept等虚函数)。不过派生的函数集的调用基类的相应方法哦。很可惜没有重写Socket.Accept方法,让它返回一个TcpEventSocket,这样应该就比较完整了,只可惜我不知道怎么做^_^,如果谁知道的话欢迎指教。

  事件通知机制已经基本完成,所缺乏的只是大量的测试(我做了几下最简单的测试,惭愧!!^_^)

  如果有问题请联系 yzx110@bit.edu.cn

来源:http://www.tulaoshi.com/n/20160219/1600684.html

延伸阅读
C#是微软随着VS.net新推出的一门语言。它作为一门新兴的语言,有着C++的强健,又有着VB等的RAD特性。而且,微软推出C#主要的目的是为了对抗Sun公司的Java。大家都知道Java语言的强大功能,尤其在网络编程方面。于是,C#在网络编程方面也自然不甘落后于人。本文就向大家介绍一下C#下实现套接字(Sockets)编程的一些基本知识,以期能使大家...
一:概念介绍 1:)资源 可以使用的系统资源.比如注册用户是一种资源,修改用户信息也是一种资源. 资源在系统中呈现为一棵树.假如用户管理是一个节点.用户注册,用户信息 修改为用户管理的叶子。叶子具有不可分割性. 2:)角色 绑定可操作资源的集合。 比如系统管理员,可以使用全部资源. 一般用户,...
标签: Web开发
文章提示 AJAX和JMX分别位于系统管理栈的两个对立端。然而,如今AJAX模型已普遍存在于丰富的浏览器客户端。这使得该模型在构架领域为在问题解析管道中提高支持模式所具有的优点变得模糊起来。 本文将详细描述一种AJAX架构的优点-它可以把管理状态"广播"到一个能够使用浏览器的用户基上而不必等待页面更新。 这种架构是一个通用模型...
首先从原理上解释一下采用Socket接口的网络通讯,这里以最常用的C/S模式作为范例,首先,服务端有一个进程(或多个进程)在指定的端口等待客户来连接,服务程序等待客户的连接信息,一旦连接上之后,就可以按设计的数据交换方法和格式进行数据传输。客户端在需要的时刻发出向服务端的连接请求。这里为了便于理解,提到了一些调用及其大致的...
异步客户端套接字示例   下面的示例程序创建一个连接到服务器的客户端。该客户端是用异步套接字生成的,因此在等待服务器返回响应时不挂起客户端应用程序的执行。该应用程序将字符串发送到服务器,然后在控制台显示该服务器返回的字符串。 C# using System; using System.Net; using System.Net.Sockets; us...

经验教程

196

收藏

78
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部