当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > 实现基于事件通知的.Net套接字

ASP.NET
使用函数传递参数来执行相应的数据库操作
如何实现在窗体和窗体之间进行传递数据
ASP.NET中文显示之两种解决方法
ASP.NET、JSP及PHP之间的抉择
ASP.NET 2.0发送电子邮件中存在的问题
谈谈HtmlControl与WebControl的区别与用途
从ASP.NET 1.1升级到ASP.NET 2.0要考虑的Cookie问题
通过系统配置来提高ASP.NET应用程序的稳定性
妙用ASP2.0中的URL映射改变网址
AJAX实现web页面中级联菜单的设计
ASP.NET跨页面传值技巧总结
再议ASP.NET DataGrid控件中的“添加新行”功能
Geometry 对象浅析
重构CollapsibleSplitter
如何利用.NET Framework使用RSS feed
ASP.NET获取IP与MAC地址的方法
在ASP.NET 2.0中使用样式、主题和皮肤
ASP.NET中为GridView添加删除提示框
ASP.NET 2.0,无刷新页面新境界
看看一个.net版对话框控件

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-13   浏览: 67 ::
收藏到网摘: n/a

以前学过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,这样应该就比较完整了,只可惜我不知道怎么做^_^,如果谁知道的话欢迎指教。
事件通知机制已经基本完成,所缺乏的只是大量的测试(我做了几下最简单的测试,惭愧!!^_^)
如果有问题请联系 [email protected]