安卓N版本ARTSPConnection::onSendRequest原文:
ARTSPConnection::onSendRequest完成向服务端发送RTSP请求。
void ARTSPConnection::onSendRequest(const sp<AMessage> &msg) {
//从消息msg里得到异步应答消息reply的引用,
//当请求发送完成后,发送该异步处理消息
sp<AMessage> reply;
CHECK(msg->findMessage("reply", &reply));
if (mState != CONNECTED) {
//如果当前的状态不是已经连接的状态,
//在异步应答消息的"result"字段设置错误码-ENOTCONN
//发送该异步应答消息进行相应的处理
reply->setInt32("result", -ENOTCONN);
reply->post();
return;
}
//从消息msg里获取要要发送是消息request
AString request;
CHECK(msg->findString("request", &request));
// Just in case we need to re-issue the request with proper authentication
// later, stash it away.
//将该消息原本的内容添加到异步应答消息的"original-request"字段
reply->setString("original-request", request.c_str(), request.size());
//对该消息request添加一些认证信息
//对于这两个函数研究将在后面进行
addAuthentication(&request);
addUserAgent(&request);
// Find the boundary between headers and the body.
//"\r\n\r\n"是消息头部和消息体的分割符
ssize_t i = request.find("\r\n\r\n");
CHECK_GE(i, 0);
int32_t cseq = mNextCSeq++;
//构造消息CSeq头部
//cseq的值表示一对儿RTSP请求和应答消息
//在客户端进行计数,由mNextCSeq进行计数每发送一个新的RTSP请求消息,就将该值自增1
AString cseqHeader = "CSeq: ";
cseqHeader.append(cseq);
cseqHeader.append("\r\n");
//将该消息头部插入到"\r\n\r\n"中间的位置
//这里是一个设计技巧,因为构造的CSeq头部的结尾是"\r\n"
//在"\r\n\r\n"中间插入构造的CSeq头部,因此就在构造的CSeq头部后形成新的"\r\n\r\n"分隔符来分割消息头部和消息体
request.insert(cseqHeader, i + 2);
ALOGV("request: '%s'", request.c_str());
size_t numBytesSent = 0;
while (numBytesSent < request.size()) {
//调用send函数将该消息发送给服务端
ssize_t n =
send(mSocket, request.c_str() + numBytesSent,
request.size() - numBytesSent, 0);
if (n < 0 && errno == EINTR) {
//如果错误码errno == EINTR说明信号被中断
//调用continue跳过当前循环,继续发送
continue;
}
if (n <= 0) {
performDisconnect();
if (n == 0) {
// Server closed the connection.
ALOGE("Server unexpectedly closed the connection.");
//send函数的返回值为0,说明服务端已经关闭了当前的连接
//在异步应答消息reply的"result"字段设置错误码ERROR_IO
reply->setInt32("result", ERROR_IO);
reply->post();
} else {
ALOGE("Error sending rtsp request. (%s)", strerror(errno));
//send函数的返回值小于0,说明发生了错误,将错误码errno设置到应答消息reply的"result"字段
reply->setInt32("result", -errno);
reply->post();
}
return;
}
numBytesSent += (size_t)n;
}
//代码执行到这里,说明RTSP请求消息已经被发送出去了,这里需要等待服务端RTSP应答消息的到来
//将cseq与异步应答消息reply存放在mPendingRequests里等待服务端RTSP应答消息的到来
mPendingRequests.add(cseq, reply);
}