CrtmpServr 接收Http流程
最近在研究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流程的更多相关文章
- 对Socket CAN的理解(4)——【Socket CAN接收数据流程】
转载请注明出处:http://blog.csdn.net/Righthek 谢谢! 如今我们来分析一下CAN总线的接收数据流程,对于网络设备.数据接收大体上採用中断+NAPI机制进行数据的接收.相同. ...
- Android Mms 接收信息流程
信息的接收工作是由底层来完成的,当有一个 新的信息时底层完成接收后会以Intent的方式来通知上层应用,信息的相关内容也包含在Intent当中,Android所支持的信息Intent都定 义在andr ...
- CKEditor+SWFUpload实现功能较为强大的编辑器(三)---后台接收图片流程
在前台配置完CKEditor和SWFUpload之后就可以满足基本的需求了 在这里,我配置的接收异步上传的图片的页面为upload.ashx 在这个ashx中对上传的图片处理的流程如下: contex ...
- stm32 usb数据接收与数据发送程序流程分析
http://blog.csdn.net/u011318735/article/details/17424349 既然学习了USB,那就必须的搞懂USB设备与USB主机数据是怎么通讯的.这里主要讲设备 ...
- Linux内核二层数据包接收流程
本文主要讲解了Linux内核二层数据包接收流程,使用的内核的版本是2.6.32.27 为了方便理解,本文采用整体流程图加伪代码的方式从内核高层面上梳理了二层数据包接收的流程,希望可以对大家有所帮助.阅 ...
- linux原始套接字(3)-构造IP_TCP发送与接收
一.概述 tcp报文封装在ip报文中,创建tcp的原始套接字如下: sockfd = socket ...
- Android 短信模块分析(四) MMS之短信的发送与接收
MMS之短信的发送与接收分析: 一.信息发送: com.android.mms.data.WorkingMessage.java 类 send()函数: public void send() { . ...
- H264-YUV通过RTP接收视频流ffmpeg解码SDL实时播放
写在前面的话 写一个简单的播放器,通过RTP接收视频流,进行实时播放.最初,使用ffplay或者vlc接收按照SDP协议文件可以播放视频,但是视频中断后重启,不能正确的解包,时常会出现如下的错误信息. ...
- S3C6410 SPI全双工读写流程分析(原创)【转】
转自:http://blog.csdn.net/hustyangju/article/details/21165721 原创博文,知识共享!转载请注明出处:http://blog.csdn.net/h ...
随机推荐
- ICCID
ICCID:Integrate circuit card identity 集成电路卡识别码(固化在手机SIM卡中) ICCID为IC卡的唯一识别号码,共有20位数字+英文组成,其编码格式为:XXX ...
- 九度oj 题目1443:Tr A
题目描述: A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973. 输入: 数据的第一行是一个T,表示有T组数据. 每组数据的第一行有n(2 <= n & ...
- Linux Shell系列教程之(五)Shell字符串
本文是Linux Shell系列教程的第(五)篇,更多shell教程请看:Linux Shell系列教程 字符串是Shell编程中最常用最有用的数据类型,今天,Linux大学网就为大家介绍一下在She ...
- Linux命令之必须掌握的十条命令
Linux现如今已经成为了软件行业最流行的操作系统,掌握Linux就成为了每一个开发者必备的专业技能. 为了方便大家学习,大学君在此为大家整理了在使用Linux时必须掌握的十条命令,希望大家能熟练掌握 ...
- 【Luogu】P3746组合数问题(矩阵)
题目链接 哇我一个活人的智商被题目碾压了 可以把问题转化为有nk个物品,问拿i件物品的方案数有多少种,其中i%k=r. 然后矩阵乘法加速DP即可. #include<cstdio> #in ...
- 【Luogu】P3155叶子的染色(树形DP)
题目链接 树形DP水题qwq. 设f[i][j]是以i为根的子树,染成j色,且满足内部需求的最少染色节点数. 设to是x的子节点,那么状态转移方程如此设计: 1.f[i][0] 这个状态表示i不染色, ...
- formData使用总结
1.formData基本使用 //可以从form元素初始化一个FormData对象,或者new一个空对象 var formData = new FormData([fromElement]); //可 ...
- MongoDb C# 驱动操作示例
c#操作mongo数据库 驱动采用http://www.oschina.net/p/mongo-csharp-driver C#驱动的基本数据库连接,增删改查操作 //定义对象 public clas ...
- 洛谷 [P2859] 摊位预定
贪心 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm ...
- luogu 3709 大爷的字符串题 构造 莫队 区间众数
题目链接 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区间中随机拿出一个字符\(x\),然后把\(x\)从这个区间中删除,你要维护一个集合S 如果\(S\)为空,你\(r ...