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

以前学过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

(0)

相关推荐

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

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

  • python粘包问题及socket套接字编程详解

    粘包问题 TCP协议在传输过程中会出现数据粘包问题 讲一下TCP和UDP的区别,都是传数据的协议,没有好坏之说,只是不同的应用需求可能会更好选择哪一个协议 TCP:适合传输数量大 ,需要建立连接,会出现粘包问题,粘包问题可以解决,确定传入的长度,接收同样长度就可以保证一次性传输完 UDP: 适合传输数据量小,没有粘包,不需要连接,一次性传输,下一次就是新的数据,弊端就是数据丢失,不安全 QQ是用什么协议呢?按理应该可以用UDP协议,但是实际用的是TCP协议,这是历史遗留问题,可还记得我们输入QQ

  • jQuery基于事件控制实现点击显示内容下拉效果

    本文实例讲述了jQuery基于事件控制实现点击显示内容下拉效果.分享给大家供大家参考,具体如下: 1.实例代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml&

  • .NET中基于事件的异步模式-EAP

    前言 在C# 5.0中,新增了async await 2个关键字支持异步编程的操作.在讲述这两个关键字之前,我先总结一下.NET中的常见的异步编程模型. 异步编程一直是比较复杂的问题,其中要处理多线程之间的数据同步.获取进度.可取消.获取结果.不影响主线程操作.多个任务之间互相不影响等,因此需要设计编程模型去处理此类问题. 从.NET 4.5开始,支持的三种异步编程模式: 基于事件的异步编程设计模式 (EAP,Event-based Asynchronous Pattern) 异步编程模型(AP

  • C++设置事件通知线程工作的方法

    本文实例讲述了C++设置事件通知线程工作的方法,其中主线程通过将事件状态设置为"受信"来通知工作线程工作.具体实现方法如下: 复制代码 代码如下: // eventDemo.cpp : 定义控制台应用程序的入口点.  //    #include "stdafx.h"  #include <Windows.h>  #include <process.h>  HANDLE g_event;    UINT __stdcall ThreadPro

  • python 基于TCP协议的套接字编程详解

    基于TCP协议的套接字编程 实现电话沟通为例,这里传递的是字符,可以自己尝试去发送一个文件 # 服务端 import socket # 1. 符合TCP协议的手机 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # TCP # 2. 绑定手机号 一个服务器,我们自己的电脑作为服务器的话,用自己的IP地址 server.bind(('127.0.0.1',8000)) # 127.0.0.1 代表本地 # server.bind(

  • dubbo新手学习之事件通知实践教程

    前言 今天主要给大家分享一下dubbo的事件通知机制. 先看下dubbo中文官网的示例解释:事件通知. 在调用之前.调用之后.出现异常时,会触发 oninvoke.onreturn.onthrow 三个事件,可以配置当事件发生时,通知哪个类的哪个方法. 实践 溪源目的是快速学习dubbo的相关机制,故定义的相同的接口和方法,采用分包的方式解耦合,便于后期维护. 先看服务接口 dubbo-demo-interface 目录如图 ** UserNotifyService ** /** * @auth

  • C#基于Socket套接字的网络通信封装

    本文为大家分享了C#基于Socket套接字的网络通信封装代码,供大家参考,具体内容如下 摘要 之所以要进行Socket套接字通信库封装,主要是直接使用套接字进行网络通信编程相对复杂,特别对于初学者而言.实际上微软从.net 2.0开始已经提供了TCP.UDP通信高级封装类如下: TcpListener TcpClient UdpClient 微软从.net 4.0开始提供基于Task任务的异步通信接口.而直接使用socket封装库,很多socket本身的细节没办法自行控制,本文目就是提供一种so

  • .NET2.0版本中基于事件的异步编程模式(EAP)

    一.引言 APM为我们实现异步编程提供了一定的支持,同时它也存在着一些明显的问题——不支持对异步操作的取消和没有提供对进度报告的功能,对于有界面的应用程序来说,进度报告和取消操作的支持也是必不可少的. 微软在.NET 2.0的时候就为我们提供了一个新的异步编程模型,也就是基于事件的异步编程模型——EAP(Event-based Asynchronous Pattern ). 二.介绍 实现了基于事件的异步模式的类将具有一个或者多个以Async为后缀的方法和对应的Completed事件,并且这些类

  • Python 网络编程之TCP客户端/服务端功能示例【基于socket套接字】

    本文实例讲述了Python 网络编程之TCP客户端/服务端功能.分享给大家供大家参考,具体如下: demo.py(TCP客户端): import socket def main(): # 1. 创建tcp的套接字 tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2. 链接服务器 # tcp_socket.connect(("192.168.33.11", 7890)) server_ip = input(

随机推荐