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 ... 
随机推荐
- python 计算日期间隔
			from datetime import date a = date(2011,11,24) b = date(2011,11,17) print(a-b) 
- 【Luogu】P2657windy数(数位DP)
			题目链接 正式迈入了数位DP的大门…… 心情激动 (看我立个flag,我如果专攻数位DP的话,到wc之前就会有秒数位DP蓝题的能力) 数位DP讲解链接 讲的非常详细,良心博客.比我写的博客加在一起还要 ... 
- POJ3071 Football  【概率dp】
			题目 Consider a single-elimination football tournament involving 2n teams, denoted 1, 2, -, 2n. In eac ... 
- kali2 install Nessus
			注册: https://www.tenable.com/products/nessus-home 安装: 设置登录用户名,密码,输入注册码: 
- java Logger 的使用与配置
			原文来自:http://blog.csdn.net/nash603/article/details/6749914 Logger所对应的属性文件在安装jdk目录下的jre/lib/logging.pr ... 
- scrapy之download middleware
			官方文档:https://docs.scrapy.org/en/latest/topics/downloader-middleware.html 一 write your own downloader ... 
- FOJ Problem 2260 Card Game
			Problem 2260 ... 
- 转 python基础学习笔记(一)
			http://www.cnblogs.com/fnng/category/454439.html 下面我们创建一个文件 root@fnngj-H24X:/hzh/python# touch hell. ... 
- Django时区配置:有次发现缓存的时间总是有问题,原来是时区配置需要改
			# LANGUAGE_CODE = 'en-us' # TIME_ZONE = 'UTC' LANGUAGE_CODE = 'zh-Hans' TIME_ZONE = 'Asia/Shanghai' 
- 呕心沥血之作:完美解决Informix的中文乱码问题
			Informix是IBM旗下的一款数据库,要不是这个项目需要,估计这辈子我都不知道居然还有这么一款数据库.想来公司的项目遍布全国各地,各种部署环境各种应用场景应有尽有,七七八八的问了一大堆的各项目组兄 ... 
