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

相关文章

5分钟获取deepseek api并搭建简易问答应用

《5分钟获取deepseekapi并搭建简易问答应用》本文主要介绍了5分钟获取deepseekapi并搭建简易问答应用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需... 目录1、获取api2、获取base_url和chat_model3、配置模型参数方法一:终端中临时将加

C#提取PDF表单数据的实现流程

《C#提取PDF表单数据的实现流程》PDF表单是一种常见的数据收集工具,广泛应用于调查问卷、业务合同等场景,凭借出色的跨平台兼容性和标准化特点,PDF表单在各行各业中得到了广泛应用,本文将探讨如何使用... 目录引言使用工具C# 提取多个PDF表单域的数据C# 提取特定PDF表单域的数据引言PDF表单是一

PyCharm接入DeepSeek实现AI编程的操作流程

《PyCharm接入DeepSeek实现AI编程的操作流程》DeepSeek是一家专注于人工智能技术研发的公司,致力于开发高性能、低成本的AI模型,接下来,我们把DeepSeek接入到PyCharm中... 目录引言效果演示创建API key在PyCharm中下载Continue插件配置Continue引言

C#实现系统信息监控与获取功能

《C#实现系统信息监控与获取功能》在C#开发的众多应用场景中,获取系统信息以及监控用户操作有着广泛的用途,比如在系统性能优化工具中,需要实时读取CPU、GPU资源信息,本文将详细介绍如何使用C#来实现... 目录前言一、C# 监控键盘1. 原理与实现思路2. 代码实现二、读取 CPU、GPU 资源信息1.

Java中Springboot集成Kafka实现消息发送和接收功能

《Java中Springboot集成Kafka实现消息发送和接收功能》Kafka是一个高吞吐量的分布式发布-订阅消息系统,主要用于处理大规模数据流,它由生产者、消费者、主题、分区和代理等组件构成,Ka... 目录一、Kafka 简介二、Kafka 功能三、POM依赖四、配置文件五、生产者六、消费者一、Kaf

使用MongoDB进行数据存储的操作流程

《使用MongoDB进行数据存储的操作流程》在现代应用开发中,数据存储是一个至关重要的部分,随着数据量的增大和复杂性的增加,传统的关系型数据库有时难以应对高并发和大数据量的处理需求,MongoDB作为... 目录什么是MongoDB?MongoDB的优势使用MongoDB进行数据存储1. 安装MongoDB

在C#中获取端口号与系统信息的高效实践

《在C#中获取端口号与系统信息的高效实践》在现代软件开发中,尤其是系统管理、运维、监控和性能优化等场景中,了解计算机硬件和网络的状态至关重要,C#作为一种广泛应用的编程语言,提供了丰富的API来帮助开... 目录引言1. 获取端口号信息1.1 获取活动的 TCP 和 UDP 连接说明:应用场景:2. 获取硬

Python MySQL如何通过Binlog获取变更记录恢复数据

《PythonMySQL如何通过Binlog获取变更记录恢复数据》本文介绍了如何使用Python和pymysqlreplication库通过MySQL的二进制日志(Binlog)获取数据库的变更记录... 目录python mysql通过Binlog获取变更记录恢复数据1.安装pymysqlreplicat

C#实现获取电脑中的端口号和硬件信息

《C#实现获取电脑中的端口号和硬件信息》这篇文章主要为大家详细介绍了C#实现获取电脑中的端口号和硬件信息的相关方法,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 我们经常在使用一个串口软件的时候,发现软件中的端口号并不是普通的COM1,而是带有硬件信息的。那么如果我们使用C#编写软件时候,如

C#实现WinForm控件焦点的获取与失去

《C#实现WinForm控件焦点的获取与失去》在一个数据输入表单中,当用户从一个文本框切换到另一个文本框时,需要准确地判断焦点的转移,以便进行数据验证、提示信息显示等操作,本文将探讨Winform控件... 目录前言获取焦点改变TabIndex属性值调用Focus方法失去焦点总结最后前言在一个数据输入表单