2.live555源码分析----服务端doEventLoop()函数分析
上一篇博客说道,live555服务端main函数做的最后一件事就是调用如下代码陷入死循环:
env->taskScheduler().doEventLoop(); // does not return
那么这个doEventLoop是什么样的呢?如下:
void BasicTaskScheduler0::doEventLoop(char* watchVariable) {
// Repeatedly loop, handling readble sockets and timed events:
while () {
if (watchVariable != NULL && *watchVariable != ) break;
SingleStep();
}
}
就是不停地调用SingleStep()这个函数,SingleStep函数中代码比较多,我下面仅截取关键代码,首先是使用selet陷入阻塞,等待事件发生:
int selectResult = select(fMaxNumSockets, &readSet, &writeSet, &exceptionSet, &tv_timeToDelay);
返回值后之后会对所有的socket进行遍历,找到是哪个socket发生了事件:
while ((handler = iter.next()) != NULL) {
int sock = handler->socketNum; // alias
int resultConditionSet = ;
if (FD_ISSET(sock, &readSet) && FD_ISSET(sock, &fReadSet)/*sanity check*/) resultConditionSet |= SOCKET_READABLE;
if (FD_ISSET(sock, &writeSet) && FD_ISSET(sock, &fWriteSet)/*sanity check*/) resultConditionSet |= SOCKET_WRITABLE;
if (FD_ISSET(sock, &exceptionSet) && FD_ISSET(sock, &fExceptionSet)/*sanity check*/) resultConditionSet |= SOCKET_EXCEPTION;
if ((resultConditionSet&handler->conditionSet) != && handler->handlerProc != NULL) {
fLastHandledSocketNum = sock;
// Note: we set "fLastHandledSocketNum" before calling the handler,
// in case the handler calls "doEventLoop()" reentrantly.
(*handler->handlerProc)(handler->clientData, resultConditionSet);
break;
}
}
if (handler == NULL && fLastHandledSocketNum >= ) {
// We didn't call a handler, but we didn't get to check all of them,
// so try again from the beginning:
iter.reset();
while ((handler = iter.next()) != NULL) {
int sock = handler->socketNum; // alias
int resultConditionSet = ;
if (FD_ISSET(sock, &readSet) && FD_ISSET(sock, &fReadSet)/*sanity check*/) resultConditionSet |= SOCKET_READABLE;
if (FD_ISSET(sock, &writeSet) && FD_ISSET(sock, &fWriteSet)/*sanity check*/) resultConditionSet |= SOCKET_WRITABLE;
if (FD_ISSET(sock, &exceptionSet) && FD_ISSET(sock, &fExceptionSet)/*sanity check*/) resultConditionSet |= SOCKET_EXCEPTION;
if ((resultConditionSet&handler->conditionSet) != && handler->handlerProc != NULL) {
fLastHandledSocketNum = sock;
// Note: we set "fLastHandledSocketNum" before calling the handler,
// in case the handler calls "doEventLoop()" reentrantly.
(*handler->handlerProc)(handler->clientData, resultConditionSet);
break;
}
}
if (handler == NULL) fLastHandledSocketNum = -;//because we didn't call a handler
}
当找到相应的的socket的时候,调用的是(*handler->handlerProc)这个函数,这个函数是什么呢?在上一篇博客里讲过,其实这个函数就是我们用turnOnBackgroundReadHandling()和相应socket绑定的函数,那么相对于一个server socket,绑定的就是incomingConnectionHandlerRTSP,主要功能是接受连接,创建新会话。如果是一个处理单个客户端的socket,那它绑定的就是incomingRequestHandler(),也就是负责从socket里读出数据,然后使用函数handleRequstBytes()对数据进行处理。
handler类型是HandlerDescriptor,这个类的定义是:
class HandlerDescriptor {
HandlerDescriptor(HandlerDescriptor* nextHandler);
virtual ~HandlerDescriptor();
public:
int socketNum;
int conditionSet;
TaskScheduler::BackgroundHandlerProc* handlerProc;
void* clientData;
private:
// Descriptors are linked together in a doubly-linked list:
friend class HandlerSet;
friend class HandlerIterator;
HandlerDescriptor* fNextHandler;
HandlerDescriptor* fPrevHandler;
};
这个类存储了select监控的socket的状况和相关参数。其中:
TaskScheduler::BackgroundHandlerProc* handlerProc;
就是当这个socket发生事件时所需要调用的函数。
2.live555源码分析----服务端doEventLoop()函数分析的更多相关文章
- Netty源码解析---服务端启动
Netty源码解析---服务端启动 一个简单的服务端代码: public class SimpleServer { public static void main(String[] args) { N ...
- zookeeper源码之服务端数据库管理中心
负责管理ZooKeeper整个数据.主要管理树结构数据.session数据.持久化管理. 类图 ZKDatabase ZooKeeper数据管理门户类,底层通过DataTree来管理树结构,通过Fil ...
- zookeeper源码之服务端
zookeeper服务端主要包括一下几个模块: 1.启动模块. 2.核心执行模块 3.数据管理模块. 启动模块 读取配置文件,启动程序.详见:zookeeper源码之服务端启动模块. 核心执行 ...
- Netty 源码学习——服务端流程分析
在上一篇我们已经介绍了客户端的流程分析,我们已经对启动已经大体上有了一定的认识,现在我们继续看对服务端的流程来看一看到底有什么区别. 服务端代码 public class NioServer { pr ...
- Netty源码解析 -- 服务端启动过程
本文通过阅读Netty源码,解析Netty服务端启动过程. 源码分析基于Netty 4.1 Netty是一个高性能的网络通信框架,支持NIO,OIO等多种IO模式.通常,我们都是使用NIO模式,该系列 ...
- kbengine mmo源码(完整服务端源码+资源+完整客户端源码)
本项目作为kbengine服务端引擎的客户端演示而写 更新kbengine插件库(https://github.com/kbengine/kbengine_unity3d_plugins): ...
- Nacos源码系列—服务端那些事儿
点赞再看,养成习惯,微信搜索[牧小农]关注我获取更多资讯,风里雨里,小农等你,很高兴能够成为你的朋友. 项目源码地址:公众号回复 nacos,即可免费获取源码 前言 在上节课中,我们讲解了客户端注册服 ...
- Hadoop RPC源码阅读-服务端Server
Hadoop版本Hadoop2.6 RPC主要分为3个部分:(1)交互协议 (2)客户端(3)服务端 (3)服务端 RPC服务端的实例代码: public class Starter { public ...
- zookeeper源码之服务端核心执行模块
服务端核心执行模块包括一下几个部分 1.leader选举. 2.
随机推荐
- paddlepaddle如何预加载embedding向量
使用小批量数据时,模型容易过拟合,所以需要对全量数据进行处理,我是用的是word2vec训练的词向量. 那么训练好对词向量如何加载呢? #!/usr/bin/env python # -*- codi ...
- Xamarin.FormsShell基础教程(7)Shell项目关于页面的介绍
Xamarin.FormsShell基础教程(7)Shell项目关于页面的介绍 轻拍标签栏中的About标签,进入关于页面,如图1.8和图1.9所示.它是对应用程序介绍的页面. 该页面源自Views文 ...
- [转]JsonCpp遍历json
#include "json.h" typedef Json::Writer JsonWriter; typedef Json::Reader JsonReader; typede ...
- Eclipse检出原MyEclipse项目后 javax.servlet.http相关类都报错【我,体现着一类jar包问题的处理方法】
用Eclipse检出原来为myEclipse搭建的一个项目,检出后,所有关于httpservlet的类都报异常,说有没实现的方法? 但这个项目之前人家用MyEclipse运行都是没有问题的, 按住CT ...
- bash命令检测Shell脚本中的语法错误和查看详细执行过程
(1).bash命令检测Shell脚本中的语法错误 bash -v [脚本] [root@youxi1 ~]# vim a.sh #/bin/bash sum=$[$1+$2] echoo $sum ...
- 人脸识别(基于ArcFace)
我们先来看看效果 上面是根据图片检测出其中的人脸.每个人脸的年龄还有性别,非常强大 第一步: 登录https://ai.arcsoft.com.cn/,注册开发者账号,身份认证,注册应用,得到APPI ...
- [Mobi] 移动端应用技术选型的思考, Native, Flutter, Quasar, React Native
今天我主要是从开发 **不同产品** 和 **技术力量差别** 两个方面来做一个比较: Native 除了两端的技术力量要求高.花的功夫多,没毛病,看你有没有这个实力. Flutter 通过实现中间层 ...
- ASP.NET Core DotNetCore 开源GitServer 实现自己的GitHub
ASP.NET Core 2.0 开源Git HTTP Server,实现类似 GitHub.GitLab. GitHub:https://github.com/linezero/GitServer ...
- chrome表单自动填充如何取消
autocomplete="new-password"
- Mysql 索引基础
[1]什么是索引?为什么要建立索引? 索引,其实就是目录. 索引,用于快速找出在某个列中有某个特定值的行. 不使用索引,MySQL必须从第一条记录开始查找整张表,直到找出相关的行,那么表越大,查询数据 ...