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

ASP.NET
asp.net GridView控件中模板列CheckBox全选、反选、取消
asp.net GridView 删除时弹出确认对话框(包括内容提示)
asp.net DropDownList 三级联动下拉菜单实现代码
asp DataTable添加列和行的三种方法
Asp.net 页面调用javascript变量的值
asp.net 长文章通过设定的行数分页
asp.net 定时间点执行任务的简易解决办法
asp.net 页面延时五秒,跳转到另外的页面
asp.net 动态输出透明gif图片
asp.net DataList与Repeater用法区别
asp.net Javascript获取CheckBoxList的value
asp.net程序在调式和发布之间图片路径问题的解决方法
asp.net下生成英文字符数字验证码的代码
asp.net 页面版文本框智能提示JSCode (升级版)
ASP.NET URL伪静态重写实现方法
ASP.NET 2.0 中Forms安全认证
asp.net 动态添加多个用户控件
asp.net Repeater显示父子表数据,无闪烁
asp.net 无法获取的内部内容,因为该内容不是文本 的解决方法
asp.net GridView排序简单实现

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


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