最近在研究CrtmpServer http部分,记录一些基本的流程,以备查阅。

首先,打开配置脚本CrtmpServer.lua ,确认脚本中有以下内容,如果没有需要加上。

  1. {
  2. name="samplefactory",
  3. description="asdsadasdsa",
  4. protocol="dynamiclinklibrary",
  5. aliases=
  6. {
  7. "httpOutboundTest"
  8. },
  9. acceptors =
  10. {
  11. {
  12. ip="0.0.0.0",
  13. port=,
  14. protocol="httpEchoProtocol"
  15. },
  16. {
  17. ip="0.0.0.0",
  18. port=,
  19. protocol="echoProtocol"
  20. }
  21. }
  22. --validateHandshake=true,
  23. --default=true,
  24. },

在浏览器地址栏中输入http://127.0.0.1:8989/httpEchoProtocol/TestHttp,跟踪CrtmpServer堆栈,调用堆栈如下图所示。

图1 CrtmpServer接收Http调用堆栈

下面逐步分析流程:

1.TCPCarrier::OnEvent(select_event &event)

Carrier层要么是udp,要么是tcp,http协议传输层采用的是http,所以是接收到Tcp链接。

CrtmpServer运行后通过Register 将Http,Tcp协议注册到一起。代码如下:

  1. vector<uint64_t> ProtocolFactory::ResolveProtocolChain(string name) {
  2. vector<uint64_t> result;
  3. if (name == "echoProtocol") {
  4. ADD_VECTOR_END(result, PT_TCP);
  5. ADD_VECTOR_END(result, PT_ECHO_PROTOCOL);
  6. } else if (name == "httpEchoProtocol") {
  7. ADD_VECTOR_END(result, PT_TCP);
  8. ADD_VECTOR_END(result, PT_INBOUND_HTTP);
  9. ADD_VECTOR_END(result, PT_ECHO_PROTOCOL);
  10. } else if (name == "httpDownload") {
  11. ADD_VECTOR_END(result, PT_TCP);
  12. ADD_VECTOR_END(result, PT_OUTBOUND_HTTP);
  13. ADD_VECTOR_END(result, PT_HTTP_DOWNLOAD_PROTOCOL);
  14. } else {
  15. ASSERT("This protocol stack should not land here");
  16. }
  17. return result;
  18. }

这段代码的调用流程如下图所示:

                   图2 httpEchoProtocol流程

tcp 从tcp链接缓存中读取数据代码如下,读取的数据放在pInputBuffer.

  1. bool TCPCarrier::OnEvent(select_event &event) {
  2. int32_t readAmount = 0;
  3. int32_t writeAmount = 0;
  4.  
  5. //3. Do the I/O
  6. switch (event.type) {
  7. case SET_READ:
  8. {
  9. IOBuffer *pInputBuffer = _pProtocol->GetInputBuffer();
  10. assert(pInputBuffer != NULL);
  11. if (!pInputBuffer->ReadFromTCPFd(_inboundFd,
  12. _recvBufferSize, readAmount)) {
  13. FATAL("Unable to read data. %s:%hu -> %s:%hu",
  14. STR(_farIp), _farPort,
  15. STR(_nearIp), _nearPort);
  16. return false;
  17. }
  18. _rx += readAmount;
  19. return _pProtocol->SignalInputData(readAmount);
  20. }

  2. 看下tcp procotol signalInputData代码

  1. bool TCPProtocol::SignalInputData(int32_t recvAmount) {
  2. _decodedBytesCount += recvAmount;
  3. return _pNearProtocol->SignalInputData(_inputBuffer);
  4. }

 _inputBuffer 中的内容如下,httpEchoProtocol/TestHttp 即是在浏览器地址上输入的http地址。

  1. GET /httpEchoProtocol/TestHttp HTTP/1.1
  2. Accept: text/html, application/xhtml+xml, image/jxr, */*
  3. Accept-Language: zh-CN
  4. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393
  5. Accept-Encoding: gzip, deflate
  6. Host: 127.0.0.1:8989
  7. Connection: Keep-Alive

  3. _pNearProtocol 实际上是BaseHTTPProtocol. _pNearProtocol->SignalInputData实际调用是BaseHTTPProtocol::SignalInputData。

SignalInputData 调用 HandleFixedLengthContent 方法,该方法会将http内容传给具体EchoProtocol,方法内容如下:

  1. bool BaseHTTPProtocol::HandleFixedLengthContent(IOBuffer &buffer) {
  2. //1. Compute the chunk size that we areg going to read
  3. //which is how many bytes we have available, but no more than _contentLength
  4. uint32_t chunkSize = GETAVAILABLEBYTESCOUNT(buffer);
  5. assert(_sessionDecodedBytesCount <= _contentLength);
  6. uint32_t remaining = _contentLength - _sessionDecodedBytesCount;
  7. chunkSize = chunkSize > remaining ? remaining : chunkSize;
  8.  
  9. //2. Update the session decoded bytes count and decoded bytes count
  10. _sessionDecodedBytesCount += chunkSize;
  11. _decodedBytesCount += chunkSize;
  12.  
  13. //3. Make the copy and ignore the chunk size
  14. _inputBuffer.ReadFromBuffer(GETIBPOINTER(buffer), chunkSize);
  15. buffer.Ignore(chunkSize);
  16.  
  17. //3. Call the near protocol
  18. if (!_pNearProtocol->SignalInputData(_inputBuffer)) {
  19. FATAL("Unable to call the next protocol in stack");
  20. return false;
  21. }
  22.  
  23. //4. reset the state if necessary
  24. if (TransferCompleted()) {
  25. _headers.Reset();
  26. _contentLength = 0;
  27. _chunkedContent = false;
  28. _lastChunk = false;
  29. _state = HTTP_STATE_HEADERS;
  30. _sessionDecodedBytesCount = 0;
  31. }
  32.  
  33. //5. we are done
  34. return true;
  35. }

  _pNearProtocol 实际是EchoProtocol

  

CrtmpServr 接收Http流程的更多相关文章

  1. 对Socket CAN的理解(4)——【Socket CAN接收数据流程】

    转载请注明出处:http://blog.csdn.net/Righthek 谢谢! 如今我们来分析一下CAN总线的接收数据流程,对于网络设备.数据接收大体上採用中断+NAPI机制进行数据的接收.相同. ...

  2. Android Mms 接收信息流程

    信息的接收工作是由底层来完成的,当有一个 新的信息时底层完成接收后会以Intent的方式来通知上层应用,信息的相关内容也包含在Intent当中,Android所支持的信息Intent都定 义在andr ...

  3. CKEditor+SWFUpload实现功能较为强大的编辑器(三)---后台接收图片流程

    在前台配置完CKEditor和SWFUpload之后就可以满足基本的需求了 在这里,我配置的接收异步上传的图片的页面为upload.ashx 在这个ashx中对上传的图片处理的流程如下: contex ...

  4. stm32 usb数据接收与数据发送程序流程分析

    http://blog.csdn.net/u011318735/article/details/17424349 既然学习了USB,那就必须的搞懂USB设备与USB主机数据是怎么通讯的.这里主要讲设备 ...

  5. Linux内核二层数据包接收流程

    本文主要讲解了Linux内核二层数据包接收流程,使用的内核的版本是2.6.32.27 为了方便理解,本文采用整体流程图加伪代码的方式从内核高层面上梳理了二层数据包接收的流程,希望可以对大家有所帮助.阅 ...

  6. linux原始套接字(3)-构造IP_TCP发送与接收

    一.概述                                                    tcp报文封装在ip报文中,创建tcp的原始套接字如下: sockfd = socket ...

  7. Android 短信模块分析(四) MMS之短信的发送与接收

     MMS之短信的发送与接收分析: 一.信息发送: com.android.mms.data.WorkingMessage.java 类 send()函数: public void send() { . ...

  8. H264-YUV通过RTP接收视频流ffmpeg解码SDL实时播放

    写在前面的话 写一个简单的播放器,通过RTP接收视频流,进行实时播放.最初,使用ffplay或者vlc接收按照SDP协议文件可以播放视频,但是视频中断后重启,不能正确的解包,时常会出现如下的错误信息. ...

  9. S3C6410 SPI全双工读写流程分析(原创)【转】

    转自:http://blog.csdn.net/hustyangju/article/details/21165721 原创博文,知识共享!转载请注明出处:http://blog.csdn.net/h ...

随机推荐

  1. WebApplicationContextUtils源码

    package org.springframework.web.context.support; import javax.servlet.ServletContext; import javax.s ...

  2. poj1006 中国剩余定理&&中国剩余定理解析

    poj 1006 题的思路不是很难的,可以转化数学式: 现设 num 是下一个相同日子距离开始的天数 p,e,i,d 如题中所设! 那么就可以得到三个式子:( num + d ) % 23 == p: ...

  3. STL之map容器的详解

    一.关于map的介绍 map是STL的 一个容器,和set一样,map也是一种关联式容器.它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键 字的值)的数据 ...

  4. manacher-模板-hd-3068

    /* 题意:给一个字符串,求该串的最长回文串的长度: 算法:Manacher O(n)复杂度,求以每一个字符为中心的最长汇文串的长度: 这个算法把奇数和偶数的情况和在一起来考虑了: */ #inclu ...

  5. Codeforces 899D Shovel Sale

    题目大意 给定正整数 $n$($2\le n\le 10^9$). 考虑无序整数对 $(x, y)$($1\le x,y\le n, x\ne y$). 求满足 「$x+y$ 结尾连续的 9 最多」的 ...

  6. hdu 1754 线段树(点修改)

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  7. 关于PHP xss 和 SQL 注入的问题

    漏洞无非这么几类,XSS.sql注入.命令执行.上传漏洞.本地包含.远程包含.权限绕过.信息泄露.cookie伪造.CSRF(跨站请求)等.这些漏洞不仅仅是针对PHP语言的,PHP如何有效防止这些漏洞 ...

  8. vue2 父子组件间通信

    父组件往子组件传值 props 传text father.vue <template> <div class="father"> {{'我是父组件'}} & ...

  9. 学习javascript设计模式之单例模式

    1.单例模式的核心是确保只有一个实例,并提供全局访问. 2.惰性单例 指的是在需要的时候才创建对象实例. 如在页面中创建唯一div 普通做法 var createDiv = (function(){  ...

  10. html css的简单学习(二)

    html css的简单学习(二) <!Doctype html>告诉浏览器,这是一个html文档.lang="en" 默认是en,表示英语:zh-Hans 中文简体:z ...