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

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

{
name="samplefactory",
description="asdsadasdsa",
protocol="dynamiclinklibrary",
aliases=
{
"httpOutboundTest"
},
acceptors =
{
{
ip="0.0.0.0",
port=,
protocol="httpEchoProtocol"
},
{
ip="0.0.0.0",
port=,
protocol="echoProtocol"
}
}
--validateHandshake=true,
--default=true,
},

在浏览器地址栏中输入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协议注册到一起。代码如下:

vector<uint64_t> ProtocolFactory::ResolveProtocolChain(string name) {
vector<uint64_t> result;
if (name == "echoProtocol") {
ADD_VECTOR_END(result, PT_TCP);
ADD_VECTOR_END(result, PT_ECHO_PROTOCOL);
} else if (name == "httpEchoProtocol") {
ADD_VECTOR_END(result, PT_TCP);
ADD_VECTOR_END(result, PT_INBOUND_HTTP);
ADD_VECTOR_END(result, PT_ECHO_PROTOCOL);
} else if (name == "httpDownload") {
ADD_VECTOR_END(result, PT_TCP);
ADD_VECTOR_END(result, PT_OUTBOUND_HTTP);
ADD_VECTOR_END(result, PT_HTTP_DOWNLOAD_PROTOCOL);
} else {
ASSERT("This protocol stack should not land here");
}
return result;
}

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

                   图2 httpEchoProtocol流程

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

bool TCPCarrier::OnEvent(select_event &event) {
int32_t readAmount = 0;
int32_t writeAmount = 0; //3. Do the I/O
switch (event.type) {
case SET_READ:
{
IOBuffer *pInputBuffer = _pProtocol->GetInputBuffer();
assert(pInputBuffer != NULL);
if (!pInputBuffer->ReadFromTCPFd(_inboundFd,
_recvBufferSize, readAmount)) {
FATAL("Unable to read data. %s:%hu -> %s:%hu",
STR(_farIp), _farPort,
STR(_nearIp), _nearPort);
return false;
}
_rx += readAmount;
return _pProtocol->SignalInputData(readAmount);
}

  2. 看下tcp procotol signalInputData代码

bool TCPProtocol::SignalInputData(int32_t recvAmount) {
_decodedBytesCount += recvAmount;
return _pNearProtocol->SignalInputData(_inputBuffer);
}

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

GET /httpEchoProtocol/TestHttp HTTP/1.1
Accept: text/html, application/xhtml+xml, image/jxr, */*
Accept-Language: zh-CN
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
Accept-Encoding: gzip, deflate
Host: 127.0.0.1:8989
Connection: Keep-Alive

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

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

bool BaseHTTPProtocol::HandleFixedLengthContent(IOBuffer &buffer) {
//1. Compute the chunk size that we areg going to read
//which is how many bytes we have available, but no more than _contentLength
uint32_t chunkSize = GETAVAILABLEBYTESCOUNT(buffer);
assert(_sessionDecodedBytesCount <= _contentLength);
uint32_t remaining = _contentLength - _sessionDecodedBytesCount;
chunkSize = chunkSize > remaining ? remaining : chunkSize; //2. Update the session decoded bytes count and decoded bytes count
_sessionDecodedBytesCount += chunkSize;
_decodedBytesCount += chunkSize; //3. Make the copy and ignore the chunk size
_inputBuffer.ReadFromBuffer(GETIBPOINTER(buffer), chunkSize);
buffer.Ignore(chunkSize); //3. Call the near protocol
if (!_pNearProtocol->SignalInputData(_inputBuffer)) {
FATAL("Unable to call the next protocol in stack");
return false;
} //4. reset the state if necessary
if (TransferCompleted()) {
_headers.Reset();
_contentLength = 0;
_chunkedContent = false;
_lastChunk = false;
_state = HTTP_STATE_HEADERS;
_sessionDecodedBytesCount = 0;
} //5. we are done
return true;
}

  _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. [git 学习篇]工作区和暂存区

    1 工作区,就是目录/User/my./learngit 2 版本库 工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库. liuzhipeng@exdroid43:~/pad/pad- ...

  2. [错误处理]Vim卡死,无法输入是怎么回事?是不是按了Ctrl+S

    在linux下使用终端的时候常常不经意的就僵死了,只能够重启来解决这个问题,后来发现常常是因为按了Ctrl+s. 经过查询Ctrl + s在终端下的含义是暂停使用该终端的用途,如果需要启用终端,需要按 ...

  3. 5款工具助你写出更好的Java代码

    1.FindBugs 顾名思义,FindBugs是一款帮助开发者发现bug的工具,它是一个开源项目,遵循GNU公共许可协议,运行的是Java字节码而不是源码. 它是一款静态分析工具,它检查类或者JAR ...

  4. google浏览器audits

    功能翻译 audits,审计 Audits help you identify and fix common problems that affect your site'sperformance,a ...

  5. [POJ2417]Discrete Logging(指数级同余方程)

    Discrete Logging Given a prime P, 2 <= P < 2 31, an integer B, 2 <= B < P, and an intege ...

  6. OSU!(bzoj 4318)

    Description osu 是一款群众喜闻乐见的休闲软件.  我们可以把osu的规则简化与改编成以下的样子:  一共有n次操作,每次操作只有成功与失败之分,成功对应1,失败对应0,n次操作对应为1 ...

  7. 以iphone6plus 为标准单位是px的页面 在运行时转换为rem

    在页面中引入以下代码,把样式中带px单位的样式放到本页面中的<style>标签中 /** * Created by Administrator on 2017-03-14. */ /*** ...

  8. dedecms--二次开发之会员帐号过期无法登录

    最近在二次开发织梦系统的会员功能:要求会员帐号有期限,开始时间以会员添加时间为开始,这样登录的时候需要判断帐号是否过期,原本的织梦系统中是通过$rs = $cfg_ml->CheckUser($ ...

  9. hdu4183往返经过至多每个点一次/最大流

    题意:从s到t,每个点有f值,只能从f值小的到大的,到T后回来,只能从f值大的到 小的,求可行否. 往返,其实就是俩条路过去(每个点最多一次),所以想到流量为2,跑最大流,看是否满2,又要每个点最多一 ...

  10. Python的格式化输出,基本运算符,编码

    一. 格式化输出现在有以下需求,让用户输入name, age, job,hobby 然后输出如下所示: -----------info of Alex Li----------- Name : Ale ...