上一篇博客说道,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()函数分析的更多相关文章

  1. Netty源码解析---服务端启动

    Netty源码解析---服务端启动 一个简单的服务端代码: public class SimpleServer { public static void main(String[] args) { N ...

  2. zookeeper源码之服务端数据库管理中心

    负责管理ZooKeeper整个数据.主要管理树结构数据.session数据.持久化管理. 类图 ZKDatabase ZooKeeper数据管理门户类,底层通过DataTree来管理树结构,通过Fil ...

  3. zookeeper源码之服务端

    zookeeper服务端主要包括一下几个模块:     1.启动模块. 2.核心执行模块 3.数据管理模块. 启动模块 读取配置文件,启动程序.详见:zookeeper源码之服务端启动模块. 核心执行 ...

  4. Netty 源码学习——服务端流程分析

    在上一篇我们已经介绍了客户端的流程分析,我们已经对启动已经大体上有了一定的认识,现在我们继续看对服务端的流程来看一看到底有什么区别. 服务端代码 public class NioServer { pr ...

  5. Netty源码解析 -- 服务端启动过程

    本文通过阅读Netty源码,解析Netty服务端启动过程. 源码分析基于Netty 4.1 Netty是一个高性能的网络通信框架,支持NIO,OIO等多种IO模式.通常,我们都是使用NIO模式,该系列 ...

  6. kbengine mmo源码(完整服务端源码+资源+完整客户端源码)

      本项目作为kbengine服务端引擎的客户端演示而写 更新kbengine插件库(https://github.com/kbengine/kbengine_unity3d_plugins):    ...

  7. Nacos源码系列—服务端那些事儿

    点赞再看,养成习惯,微信搜索[牧小农]关注我获取更多资讯,风里雨里,小农等你,很高兴能够成为你的朋友. 项目源码地址:公众号回复 nacos,即可免费获取源码 前言 在上节课中,我们讲解了客户端注册服 ...

  8. Hadoop RPC源码阅读-服务端Server

    Hadoop版本Hadoop2.6 RPC主要分为3个部分:(1)交互协议 (2)客户端(3)服务端 (3)服务端 RPC服务端的实例代码: public class Starter { public ...

  9. zookeeper源码之服务端核心执行模块

    服务端核心执行模块包括一下几个部分 1.leader选举. 2.

随机推荐

  1. CatBoost使用GPU实现决策树的快速梯度提升CatBoost Enables Fast Gradient Boosting on Decision Trees Using GPUs

    python机器学习-乳腺癌细胞挖掘(博主亲自录制视频)https://study.163.com/course/introduction.htm?courseId=1005269003&ut ...

  2. Celery 服务搭建

    整个项目工程如下 __init__.py """ 注意点:python3.7 需要执行 pip install --upgrade https://github.com/ ...

  3. 002-Python3-基础语法-赋值、显示类型、数据类型[数值、字符串、列表、元祖、集合、字典]

    一.基础语法 参看地址:https://www.runoob.com/python3/python3-tutorial.html 基础数据类型 Python 中的变量不需要声明.每个变量在使用前都必须 ...

  4. Android studio:URI is not registered 的解决办法

    今天新导入一个android studio的工程,发现在布局文件中报URI is not registerd的错误,布局文件的命名空间变成红色的了. 解决方案: 进入 File->Setting ...

  5. maven安装和应用

    maven安装和应用 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 https://www.cnblogs.com/xihehua/p/9639045.html https://w ...

  6. Nginx添加静态页面

    1.编辑配置文件 sudo vim /etc/nginx/nginx.conf 在http {}中添加如下 server { listen 80; server_name localhost; loc ...

  7. EasyNVR网页摄像机无插件H5、谷歌Chrome直播方案安装使用常见问题的分析

    EasyNVR对于互联网的视频直播还是有着一定的贡献的.为了方便用户的体验使用,我们也在互联网上放置了对应的试用版本,并且也会随着功能是更新也会定期的更新上去.软件包也会配置对应的使用文档和说明. 许 ...

  8. PS,大鹏视频,UI美工设计, 精品课程视频(500G)

    PS,大鹏视频,UI美工设计, 精品课程视频(500G 左右) ,需要的可以加我QQ 358918610 //--------------------------------------------- ...

  9. kafka备份原理

  10. vue中methods、computed、watch区别

    vue中methods.computed.watch区别methods:事件调用的钩子 computed:{ // 计算属性是根据他依赖的值计算的,当依赖值发生变化,其跟着改变 // 计算属性是依赖缓 ...