NuPlayer从服务端获取应答消息流程

2024-06-04 03:08

本文主要是介绍NuPlayer从服务端获取应答消息流程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  本文具体介绍NuPlayer获取应答消息的代码流程,流程设计到的每一个行数的详细介绍在之前的文章都有介绍。
  下一篇文章介绍接收到服务端发送来的应答消息后的处理过程:
  ARTSPConnection::notifyResponseListener函数完成这个流程。
  

==>
void ARTSPConnection::performConnect(const sp<AMessage> &reply,AString host, unsigned port) {struct hostent *ent = gethostbyname(host.c_str());if (ent == NULL) {ALOGE("Unknown host %s", host.c_str());reply->setInt32("result", -ENOENT);reply->post();mState = DISCONNECTED;return;}mSocket = socket(AF_INET, SOCK_STREAM, 0);if (mUIDValid) {HTTPBase::RegisterSocketUserTag(mSocket, mUID,(uint32_t)*(uint32_t*) "RTSP");HTTPBase::RegisterSocketUserMark(mSocket, mUID);}MakeSocketBlocking(mSocket, false);struct sockaddr_in remote;memset(remote.sin_zero, 0, sizeof(remote.sin_zero));remote.sin_family = AF_INET;remote.sin_addr.s_addr = *(in_addr_t *)ent->h_addr;remote.sin_port = htons(port);int err = ::connect(mSocket, (const struct sockaddr *)&remote, sizeof(remote));reply->setInt32("server-ip", ntohl(remote.sin_addr.s_addr));if (err < 0) {if (errno == EINPROGRESS) {sp<AMessage> msg = new AMessage(kWhatCompleteConnection, this);msg->setMessage("reply", reply);msg->setInt32("connection-id", mConnectionID);msg->post();return;}reply->setInt32("result", -errno);mState = DISCONNECTED;if (mUIDValid) {HTTPBase::UnRegisterSocketUserTag(mSocket);HTTPBase::UnRegisterSocketUserMark(mSocket);}close(mSocket);mSocket = -1;} else {reply->setInt32("result", OK);mState = CONNECTED;mNextCSeq = 1;//==>postReceiveReponseEvent();}reply->post();
} ==>
void ARTSPConnection::postReceiveReponseEvent() {if (mReceiveResponseEventPending) {return;}sp<AMessage> msg = new AMessage(kWhatReceiveResponse, this);msg->post();mReceiveResponseEventPending = true;
} ==>
void ARTSPConnection::onMessageReceived(const sp<AMessage> &msg) {switch (msg->what()) {case kWhatConnect:onConnect(msg);break;case kWhatDisconnect:onDisconnect(msg);break;case kWhatCompleteConnection:onCompleteConnection(msg);break;case kWhatSendRequest:onSendRequest(msg);break;case kWhatReceiveResponse://==>onReceiveResponse();break;case kWhatObserveBinaryData:{CHECK(msg->findMessage("reply", &mObserveBinaryMessage));break;}default:TRESPASS();break;}
}==>
void ARTSPConnection::onReceiveResponse() {mReceiveResponseEventPending = false;if (mState != CONNECTED) {return;}struct timeval tv;tv.tv_sec = 0;tv.tv_usec = kSelectTimeoutUs;fd_set rs;FD_ZERO(&rs);FD_SET(mSocket, &rs);int res = select(mSocket + 1, &rs, NULL, NULL, &tv);if (res == 1) {MakeSocketBlocking(mSocket, true);//==>bool success = receiveRTSPReponse();MakeSocketBlocking(mSocket, false);if (!success) {// Something horrible, irreparable has happened.flushPendingRequests();return;}}postReceiveReponseEvent();
}==>
bool ARTSPConnection::receiveRTSPReponse() {AString statusLine;if (!receiveLine(&statusLine)) {return false;}if (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;}sp<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;}bool isRequest = false;if (!IsRTSPVersion(AString(response->mStatusLine, 0, space1))) {CHECK(IsRTSPVersion(AString(response->mStatusLine,space2 + 1,response->mStatusLine.size() - space2 - 1)));isRequest = true;response->mStatusCode = 0;} else {AString statusCodeStr(response->mStatusLine, space1 + 1, space2 - space1 - 1);if (!ParseSingleUnsignedLong(statusCodeStr.c_str(), &response->mStatusCode)|| response->mStatusCode < 100 || response->mStatusCode > 999) {return false;}}AString line;ssize_t lastDictIndex = -1;for (;;) {if (!receiveLine(&line)) {break;}if (line.empty()) {break;}ALOGV("line: '%s'", line.c_str());if (line.c_str()[0] == ' ' || line.c_str()[0] == '\t') {// Support for folded header values.if (lastDictIndex < 0) {// First line cannot be a continuation of the previous one.return false;}AString &value = response->mHeaders.editValueAt(lastDictIndex);value.append(line);continue;}ssize_t colonPos = line.find(":");if (colonPos < 0) {// Malformed header line.return false;}AString key(line, 0, colonPos);key.trim();key.tolower();line.erase(0, colonPos + 1);lastDictIndex = response->mHeaders.add(key, line);}for (size_t i = 0; i < response->mHeaders.size(); ++i) {response->mHeaders.editValueAt(i).trim();}unsigned long contentLength = 0;ssize_t i = response->mHeaders.indexOfKey("content-length");if (i >= 0) {AString value = response->mHeaders.valueAt(i);if (!ParseSingleUnsignedLong(value.c_str(), &contentLength)) {return false;}}if (contentLength > 0) {response->mContent = new ABuffer(contentLength);if (receive(response->mContent->data(), contentLength) != OK) {return false;}}if (response->mStatusCode == 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;}}//==>return isRequest? handleServerRequest(response): notifyResponseListener(response);
}==>
bool ARTSPConnection::notifyResponseListener(const sp<ARTSPResponse> &response) {ssize_t i;status_t err = findPendingRequest(response, &i);if (err == OK && i < 0) {// An unsolicited server response is not a problem.return true;}if (err != OK) {return false;}sp<AMessage> reply = mPendingRequests.valueAt(i);mPendingRequests.removeItemsAt(i);reply->setInt32("result", OK);reply->setObject("response", response);reply->post();return true;
}

这篇关于NuPlayer从服务端获取应答消息流程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Python获取浏览器Cookies的四种方式小结

《Python获取浏览器Cookies的四种方式小结》在进行Web应用程序测试和开发时,获取浏览器Cookies是一项重要任务,本文我们介绍四种用Python获取浏览器Cookies的方式,具有一定的... 目录什么是 Cookie?1.使用Selenium库获取浏览器Cookies2.使用浏览器开发者工具

Java获取当前时间String类型和Date类型方式

《Java获取当前时间String类型和Date类型方式》:本文主要介绍Java获取当前时间String类型和Date类型方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录Java获取当前时间String和Date类型String类型和Date类型输出结果总结Java获取

Spring Boot 中的默认异常处理机制及执行流程

《SpringBoot中的默认异常处理机制及执行流程》SpringBoot内置BasicErrorController,自动处理异常并生成HTML/JSON响应,支持自定义错误路径、配置及扩展,如... 目录Spring Boot 异常处理机制详解默认错误页面功能自动异常转换机制错误属性配置选项默认错误处理

C#监听txt文档获取新数据方式

《C#监听txt文档获取新数据方式》文章介绍通过监听txt文件获取最新数据,并实现开机自启动、禁用窗口关闭按钮、阻止Ctrl+C中断及防止程序退出等功能,代码整合于主函数中,供参考学习... 目录前言一、监听txt文档增加数据二、其他功能1. 设置开机自启动2. 禁止控制台窗口关闭按钮3. 阻止Ctrl +

Spring Boot从main方法到内嵌Tomcat的全过程(自动化流程)

《SpringBoot从main方法到内嵌Tomcat的全过程(自动化流程)》SpringBoot启动始于main方法,创建SpringApplication实例,初始化上下文,准备环境,刷新容器并... 目录1. 入口:main方法2. SpringApplication初始化2.1 构造阶段3. 运行阶

使用Go实现文件复制的完整流程

《使用Go实现文件复制的完整流程》本案例将实现一个实用的文件操作工具:将一个文件的内容完整复制到另一个文件中,这是文件处理中的常见任务,比如配置文件备份、日志迁移、用户上传文件转存等,文中通过代码示例... 目录案例说明涉及China编程知识点示例代码代码解析示例运行练习扩展小结案例说明我们将通过标准库 os

RabbitMQ消息总线方式刷新配置服务全过程

《RabbitMQ消息总线方式刷新配置服务全过程》SpringCloudBus通过消息总线与MQ实现微服务配置统一刷新,结合GitWebhooks自动触发更新,避免手动重启,提升效率与可靠性,适用于配... 目录前言介绍环境准备代码示例测试验证总结前言介绍在微服务架构中,为了更方便的向微服务实例广播消息,

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

Ubuntu 24.04启用root图形登录的操作流程

《Ubuntu24.04启用root图形登录的操作流程》Ubuntu默认禁用root账户的图形与SSH登录,这是为了安全,但在某些场景你可能需要直接用root登录GNOME桌面,本文以Ubuntu2... 目录一、前言二、准备工作三、设置 root 密码四、启用图形界面 root 登录1. 修改 GDM 配

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文