ARTSPConnection::receiveRTSPReponse

2024-06-04 03:08

本文主要是介绍ARTSPConnection::receiveRTSPReponse,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

bool ARTSPConnection::receiveRTSPReponse() {AString statusLine;//调用函数receiveLine从套接口获取服务端消息的第一行,在下文被称为状态行statusLineif (!receiveLine(&statusLine)) {return false;}if (statusLine == "$") {//如果状态行statusLine为字符"$",则需要接收二进制数据//这里不具体讨论如何接收二进制数据sp<ABuffer> buffer = receiveBinaryData();if (buffer == NULL) {return false;}if (mObserveBinaryMessage != NULL) {sp<AMessage> notify = mObserveBinaryMessage->dup();notify->setBuffer("buffer", buffer);notify->post();} else {ALOGW("received binary data, but no one cares.");}return true;}//创建一个ARTSPResponse类对象来表述一个服务端的消息//将状态行赋给该对象的成员变量mStatusLinesp<ARTSPResponse> response = new ARTSPResponse;response->mStatusLine = statusLine;ALOGI("status: %s", response->mStatusLine.c_str());ssize_t space1 = response->mStatusLine.find(" ");if (space1 < 0) {return false;}ssize_t space2 = response->mStatusLine.find(" ", space1 + 1);if (space2 < 0) {return false;}//布尔变量isRequest 是用来表示该RTSP消息是请求消息还是应答消息//即用来判断该消息是服务端发送过来的请求消息还是服务端发送来的应答消息//具体的判别方法是根据版本号"RTSP/1.0"在状态行statusLine存放的位置//对于请求消息的第一行:方法 URI RTSP版本 CR LF //对于回应消息的第一行:RTSP版本 状态码 解释 CR LFbool isRequest = false;if (!IsRTSPVersion(AString(response->mStatusLine, 0, space1))) {//如果IsRTSPVersion(AString(response->mStatusLine, 0, space1)的返回值不为真说明mStatusLine[0,space1]存放的不是版本号"RTSP/1.0"//如果IsRTSPVersion(//            AString(//                response->mStatusLine,//                space2 + 1,//                response->mStatusLine.size() - space2 - 1))//的调用值为真说明mStatusLine[space2 + 1,response->mStatusLine.size() - space2 - 1]存放的是版本号"RTSP/1.0"//则该消息为服务端发送过来的请求消息,将isRequest 设置为 true//将response对象的成员变量mStatusCode状态码设置为0,因为只有回应消息才有状态码CHECK(IsRTSPVersion(AString(response->mStatusLine,space2 + 1,response->mStatusLine.size() - space2 - 1)));isRequest = true;response->mStatusCode = 0;} else {//代码执行到else分支说明IsRTSPVersion(AString(response->mStatusLine, 0, space1)返回值为真//说明mStatusLine[0,space1]存放的是版本号"RTSP/1.0",由于isRequest初始值为false,所以在这里不需要再赋值为false了//从mStatusLine[space1 + 1,space2 - space1 - 1]获取到状态码的字符表示AString statusCodeStr(response->mStatusLine, space1 + 1, space2 - space1 - 1);//调用ParseSingleUnsignedLong函数将字符表示的状态码转换成整数表示的状态码,并赋值为response的成员变量mStatusCode//状态码有效的整数值范围为100~999(包括100和999)if (!ParseSingleUnsignedLong(statusCodeStr.c_str(), &response->mStatusCode)|| response->mStatusCode < 100 || response->mStatusCode > 999) {return false;}}//代码执行到这里成功判断了该消息是服务端发送来的回应消息还是请求消息,由布尔变量isRequest表示//接下来要获取消息后续的行,紧接着是消息头headers,会有多个消息头//一个消息头占据一到多个行,若占据多个行,后续的行开头用空格' '或者制表符'\t'来标识AString line;//lastDictIndex变量用来标识上一个消息头在对象response的成员变量mHeaders容器里存放的位置ssize_t lastDictIndex = -1;//采用一个无限循环来获取剩余的所有的行for (;;) {//调用函数receiveLine来获取一行if (!receiveLine(&line)) {break;}//如果该行为空,则停止获取,终止循环if (line.empty()) {break;}ALOGV("line: '%s'", line.c_str());//如果获取的该行首字符为' '或者'\t'则,说明该回去的一行是上一行携带的参数值//将该行和上一行合并在一起if (line.c_str()[0] == ' ' || line.c_str()[0] == '\t') {// Support for folded header values.if (lastDictIndex < 0) {//lastDictIndex变的值为负,说明没有任何行添加到了对象response的成员变量mHeaders容器里//既然该获取的行又被表示为上一行携带的参数,显然是发生了错误// First line cannot be a continuation of the previous one.return false;}//根据lastDictIndex变量得到上一行在response的成员变量mHeaders容器里存放的引用AString &value = response->mHeaders.editValueAt(lastDictIndex);//将该被表示为上一行引用的一行和上一行进行合并//continue跳出本次循环继续获取下一行value.append(line);continue;}//代码执行到这里说明该行的首字符不是' '或者'\t',说明该行是一个header//给一个header的例子,Accept: application/rtsl, application/sdp;level=2//冒号前的字符是该header的key//查找冒号在改行的位置colonPosssize_t colonPos = line.find(":");if (colonPos < 0) {//如果colonPos的值小于0,则说明该行是一个错误的header line// Malformed header line.return false;}//从该行获取该行的header line的keyAString key(line, 0, colonPos);key.trim();key.tolower();//将该行的header line的key从该行删除line.erase(0, colonPos + 1);//用key,value的方式将该header line的key与其内容保存在response->mHeaders容器里//并将其保存的位置索引保存在变量lastDictIndex中lastDictIndex = response->mHeaders.add(key, line);}//代码执行到这里,已经跳出了for循环for (size_t i = 0; i < response->mHeaders.size(); ++i) {response->mHeaders.editValueAt(i).trim();}//开始分析key为content-length的header lineunsigned long contentLength = 0;ssize_t i = response->mHeaders.indexOfKey("content-length");if (i >= 0) {//根据content-length这一个header line存放的位置索引i得到该header line 的valueAString value = response->mHeaders.valueAt(i);//调用ParseSingleUnsignedLong将该content-length的值的字符表示转换成整数表示if (!ParseSingleUnsignedLong(value.c_str(), &contentLength)) {return false;}}if (contentLength > 0) {//如果contentLength的值大于0,则需要创建一个buffer并调用receive函数从创建的套接口获取内容//并将缓冲区的引用赋值给response->mContentresponse->mContent = new ABuffer(contentLength);if (receive(response->mContent->data(), contentLength) != OK) {return false;}}if (response->mStatusCode == 401) {//对状态码为401的回应消息做特别的处理if (mAuthType == NONE && mUser.size() > 0&& parseAuthMethod(response)) {ssize_t i;CHECK_EQ((status_t)OK, findPendingRequest(response, &i));CHECK_GE(i, 0);sp<AMessage> reply = mPendingRequests.valueAt(i);mPendingRequests.removeItemsAt(i);AString request;CHECK(reply->findString("original-request", &request));sp<AMessage> msg = new AMessage(kWhatSendRequest, this);msg->setMessage("reply", reply);msg->setString("request", request.c_str(), request.size());ALOGI("re-sending request with authentication headers...");onSendRequest(msg);return true;}}//对RTSP消息进行处理//如果isRequest为真,说明response是服务端发送过来的请求消息则调用handleServerRequest(response)处理服务端发送来的请求消息//如果isRequest不为真说明response是服务端发送过来的回应消息,调用notifyResponseListener(response)函数处理服务端发送过来的消息return isRequest? handleServerRequest(response): notifyResponseListener(response);
}

这篇关于ARTSPConnection::receiveRTSPReponse的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1028889

相关文章

ARTSPConnection::receiveLine

1.RTSP消息格式的格式   RTSP的消息有两大类: 请求消息(request), 回应消息(response).      请求消息: 方法 URI RTSP版本 CR LF 消息头 CR LFCR LF 消息体 CR LF   其中方法包括OPTION回应中所有的命令,URI是接受方的地址,例如:rtsp://192.168.20.136. RTSP版本一般都是 RTS

ARTSPConnection::receive

1.recv函数介绍   int recv( SOCKET s, char FAR *buf, int len, int flags );   不论是客户端还是服务器端应用程序都用recv函数从TCP连接的另一端接收数据。   参数解释:     1.参数s指定接收端套接字描述符;     2.参数buf指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据     3.参数len指

ARTSPConnection::postReceiveReponseEvent启动发送请求循环

下面贴出安卓N版本ARTSPConnection是如何启动向服务端发送请求,接收服务端的响应这样一个循环的:    ==>void ARTSPConnection::postReceiveReponseEvent() {//mReceiveResponseEventPending条件变量一旦postReceiveReponseEvent被调用就设置为true,知道整个循环调用达到末端该m