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

ASP.NET
asp.net Server.MapPath方法注意事项
asp.net下常用的加密算法MD5、SHA-1应用代码
几个 ASP.NET 小技巧
ASP.NET内置对象之Application对象
ASP.NET使用正则表达式屏蔽垃圾信息
asp.net“服务器应用程序不可用” 解决方法
asp.net Linq把数据导出到Excel的代码
asp.net ext treepanel 动态加载XML的实现方法
silverlight2.0Beta版TextBox输入中文解决方法
asp.net转出json格式客户端显示时间
asp.net下Linq To Sql注意事项小结
ASP.NET动态加载用户控件的实现方法
asp.net web大文件上传带进度条实例代码
asp.net DZ论坛中根据IP地址取得所在地的代码
向asp.Net进发 数据库连接操作
.net 上传文件前所未有的简单
asp.net gridview代码绑定
asp.net中List的使用方法
Asp.net(C#)实现验证码功能代码
asp.NET开发中正则表达式中BUG分析

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-13   浏览: 120 ::
收藏到网摘: 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]