惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 【当耐特】
Help Net Security
Help Net Security
P
Proofpoint News Feed
J
Java Code Geeks
爱范儿
爱范儿
Last Week in AI
Last Week in AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
F
Full Disclosure
Google DeepMind News
Google DeepMind News
H
Help Net Security
G
Google Developers Blog
Jina AI
Jina AI
Vercel News
Vercel News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
L
Lohrmann on Cybersecurity
S
Schneier on Security
Microsoft Azure Blog
Microsoft Azure Blog
IT之家
IT之家
Security Archives - TechRepublic
Security Archives - TechRepublic
阮一峰的网络日志
阮一峰的网络日志
N
News and Events Feed by Topic
GbyAI
GbyAI
B
Blog
O
OpenAI News
博客园_首页
Cisco Talos Blog
Cisco Talos Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Hacker News: Ask HN
Hacker News: Ask HN
TaoSecurity Blog
TaoSecurity Blog
腾讯CDC
MongoDB | Blog
MongoDB | Blog
M
MIT News - Artificial intelligence
C
Cybersecurity and Infrastructure Security Agency CISA
Cyberwarzone
Cyberwarzone
Webroot Blog
Webroot Blog
Simon Willison's Weblog
Simon Willison's Weblog
Y
Y Combinator Blog
C
Cisco Blogs
A
Arctic Wolf
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
T
The Exploit Database - CXSecurity.com
Security Latest
Security Latest
AI
AI
W
WeLiveSecurity
aimingoo的专栏
aimingoo的专栏
The Register - Security
The Register - Security
Project Zero
Project Zero
H
Hackread – Cybersecurity News, Data Breaches, AI and More
N
Netflix TechBlog - Medium
Blog — PlanetScale
Blog — PlanetScale

博客园 - MainIsUsed

svg札记 rabbitmq 小记 nfc相关 MI卡UID oracle9i导入导出命令 (转)C++中指针和引用的区别 .net下的office开发(visio对象) 关于DataTable的GetChanges()方法 【转】C#中的非安全编程(key:unsafe,fixed) Oracle中UTL_FILE包的UTL_FILE.FOPEN用法 c# 获取串口设备的输入(unsigned char *和 char*) URL字符串编码 笔记HTML - MainIsUsed - 博客园 .net导出为powerpoint的一些参考代码 关于ClickOnce 发布过程中的错误:要求高版本的CAPICOM.dll Oracle EXTRACT()函数与to_char() 函数 c#接口使用方法 - MainIsUsed - 博客园 在 WinForm 中完整支持在多级目录中保存的 ASP.NET (转) - MainIsUsed (转)什么是套接字(Socket)?
(转)实现基于事件通知的.Net套接字
MainIsUsed · 2007-10-22 · via 博客园 - MainIsUsed

 以前学过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,这样应该就比较完整了,只可惜我不知道怎么做^_^,如果谁知道的话欢迎指教。

posted on 2007-10-22 17:34  MainIsUsed  阅读(422)  评论()    收藏  举报