一个简单的BitTorrent客户端实现(三):同步事件分离器
关于同步事件分离器
了解ACE的同学想必都知道它使用了Reactor的设计模式,ACE开发的应用程序中,有个地方会调用eventloop,里面会不停地去轮询。当询到事件时,就将事件分发给指定的事件处理器,事件处理器里面有一些什么handle_read,handle_write之类的函数来响应事件。本程序也借鉴了这种模式,这样使程序结构上变得更加清晰,理解起来也更容易些。
同步事件分离器实现
本程序中的同步分离器基于套接字select函数实现,另外我们还监视定时器事件。
先说select吧,大家都知道select用于等待某个描述就绪,要么可写,要么可读,或者出错,select函数就会返回。为实现这一功能,我们需要两个描述符集,一个读,另外一个写。每次select前都会先清一下描述符集再添加。下面是实现代码:
int CSelectReactor::SelectSocket()
{ClearFdSet();AddToFdSet();int nRet = 0;timeval tmval;tmval.tv_sec = 1;tmval.tv_usec = 0;nRet = select(m_nMaxSocketFd + 1, &m_rSet, &m_wSet, NULL, &tmval);if (nRet > 0){vector<ISocket *>::iterator it = m_vecSockets.begin();for (; it != m_vecSockets.end(); ++it){if (FD_ISSET((*it)->GetHandle(), &m_rSet)){int nRes = (*it)->HandleRead();if (nRes == -1){(*it)->HandleClose();(*it)->SetReactor(NULL);(*it)->Close();continue;}}if (FD_ISSET((*it)->GetHandle(), &m_wSet)){int nRes = (*it)->HandleWrite();if (nRes == -1){(*it)->HandleClose();(*it)->SetReactor(NULL);(*it)->Close();continue;}}}}return nRet;
}
当有事件来临时,我们转到相应的事件处理函数,如HandleRead和HandleWrite,事件处理函数里面具体的实现逻辑,后面作详细介绍。
关于定时器事件,是在UpdateTimerList函数中实现的。我们需要维护一个定时器队列,把要监视的事件加入到队列中。时间到了会调用指定pCallback的OnTimer事件处理函数。
void CSelectReactor::UpdateTimerList()
{list<TimerInfo>::iterator it = m_lstTimerInfo.begin();for (; it != m_lstTimerInfo.end(); ){if (it->bRemove == true){m_lstFreeTimerID.push_back(it->nTimerID);it = m_lstTimerInfo.erase(it);continue;}if (GetTickCount() >= it->llLastshotTick + it->nInterval){it->pCallback->OnTimer(it->nTimerID);it->llLastshotTick = GetTickCount();if(it->bOneShot){m_lstFreeTimerID.push_back(it->nTimerID);it = m_lstTimerInfo.erase(it);continue;}}++it;}
这两件事情都是在另外一个线程中做的,当任务启动时,会创建线程,里面就会做这个事情。
程序源代码下载地址:http://download.csdn.net/detail/zxywd/9415711
一个简单的BitTorrent客户端实现(三):同步事件分离器相关推荐
- 一个简单的BitTorrent客户端实现(六):peer manager和peer实现
peer manager和peer peer是整个BT通信中最复杂的部分,主要是里面各种消息的发送和一些choke和unchoke策略,piece选择策略等等.peer manager用于管理peer ...
- 一个简单的BitTorrent客户端实现(二):种子文件解析及信息保存
关于种子文件 BT的种子文件一般是以.torrent作为后缀的.关于种子文件的编码,这里不再做任何介绍.本程序采用的测试种子文件为ubuntu-14.04.3-desktop-i386.torrent ...
- 一个简单的BitTorrent客户端实现(五):tracker manager和tracker实现
关于tracker和tracker manager tracker在整个bt协议中起着很重要的作用,从tracker那里我们可以获取当前正在下载的peer列表,从而与它们交互,进行文件的上传和下载.T ...
- 制作一个简单的新闻客户端
前面的博客中介绍了在Android中实现网络通信,这篇博客将是对前面介绍的技术的一个综合运用,制作一个简单的新闻客户端,在这个新闻客户端中用到了ListView.ListView的优化.使用开源框架访 ...
- java 客户端 tcp_一个简单的Tcp客户端
一个简单的Tcp客户端 import java.io.InputStream; import java.net.InetAddress; import java.net.Socket; public ...
- Golang实现一个简单的FTP客户端
使用Golang语言实现的一个简单的FTP客户端:Github源码:Golang实现一个简单的FTP客户端
- 从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator?
从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator? 原文:从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator? 从PRISM开始学 ...
- libhv教程11--创建一个简单的HTTP客户端
文章目录 简单的同步HTTP客户端示例 简单的异步HTTP客户端示例 完整的HTTP客户端示例 简单的同步HTTP客户端示例 同步http客户端接口模拟实现了python的requests #incl ...
- 使用PlayCanvas制作一个简单的小游戏(三)
原文:http://developer.playcanvas.com/zh/tutorials/beginner/keepyup-part-three/ 游戏脚本和输入 在场景的根实体Game上绑定了 ...
- libhv教程13--创建一个简单的WebSocket客户端
文章目录 WebSocket简介 WebSocket 产生背景 WebSocket 的定义 WebSocket 握手过程 WebSocket 通信协议 示例代码 js示例代码 c++示例代码 WebS ...
最新文章
- ArrayDeque中的取余
- Github 开源项目(一)websocketd (实战:实时监控服务器内存信息)
- 若依微服务版怎样在common-core模块下引用第三方lib的jar包(MobileIMSDK4J_tcp的jar包)
- python股票数据预处理_Python股票处理之六_数据预处理A
- blob 图片_前端JS实现字符串/图片/excel文件下载
- 数据结构---哈夫曼树
- P1712-[NOI2016]区间【线段树,尺取法】
- java undo_用JAVA实现Undo、Redo,Copy、Paste、Cut_java
- 最多开启多少个线程_中国到底有多少个海岛?全球海岛最多国家,我国排第几?...
- gvim最简化设置,去掉工具栏和菜单栏
- QWidget *parent
- 树、森林和二叉树的转换
- java中线程的优先级别
- Python3安装cx_Oracle连接oracle数据库实操总结
- EXCEL 数据透视表的简单使用
- kindle 耗电飞速,电池坏了?你可能给kindle“吃了有毒的食物”
- Makefile往工程文件.prj传参(或者其他文件)
- 基本数据类型的默认值
- EXTJS资源库管理平台 2013.5.26-在线制作头像
- 字节女测试工程师万字总结的软件测试入门技巧
热门文章
- Python——click模块
- 横向时间轴插件 html5,jQuery横向滚动时间轴插件
- mysql select_type simple_mysql explain
- Monorepo + lerna rush.js
- python里面snip什么意思_文献检索里面SJR是什么,SNIP指标是什么
- Oracle 对表空间无操作权限
- 用Python画一个精确的中国地图(数据+代码10行)
- 轻松禁止自动更新FLASH插件有绝招
- 网吧游戏服务器虚拟机,用虚拟机亲自体验网咖无盘系统,终于知道网咖系统快的原因了...
- i78700k配什么显卡好_i7 8700k配什么主板好?适合Intel八代i7-8700k处理器搭配的主板推荐...