您的位置:首页 > 其它

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

2017-03-08 14:46 148 查看
  下面贴出安卓N版本ARTSPConnection是如何启动向服务端发送请求,接收服务端的响应这样一个循环的:

  

==>
void ARTSPConnection::postReceiveReponseEvent() {
//mReceiveResponseEventPending条件变量一旦postReceiveReponseEvent被调用就设置为true,知道整个循环调用达到末端该mReceiveResponseEventPending才会被设置为false,这样保证一次只存在一个这样的循环处理
if (mReceiveResponseEventPending) {
return;
}

//新建一个消息msg,消息名为kWhatReceiveResponse,消息的处理者为this,也即ARTSPConnection
//则该消息的处理发生在ARTSPConnection::onMessageReceived的case kWhatReceiveResponse处理分支
sp<AMessage> msg = new AMessage(kWhatReceiveResponse, this);
msg->post();

//将mReceiveResponseEventPending变量设置为true,表示当前这样的一个循环正在进行中,不能再产生一次这样的循环。
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()函数对消息名为kWhatReceiveResponse的消息进行处理
onReceiveResponse();
break;

case kWhatObserveBinaryData:
{
CHECK(msg->findMessage("reply", &mObserveBinaryMessage));
break;
}

default:
TRESPASS();
break;
}
}

==>
void ARTSPConnection::onReceiveResponse() {
//这样的一次循环调用接近到了末端,mReceiveResponseEventPending设置为false,表示可以再进行一次这样的循环调用了
mReceiveResponseEventPending = false;

if (mState != CONNECTED) {
return;
}

//创建一个timeval类型的时间结构体变量
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = kSelectTimeoutUs;

//创建一个套接字描述符集合rs
//并将该套接字描述符集合内存清零
fd_set rs;
FD_ZERO(&rs);
//将之前创建的套接字描述符mSocket添加到该套接字描述符集合中
FD_SET(mSocket, &rs);

//调用select函数检查套接字描述符集合rs里添加的套接字的状态,
//即查询它的可读性、可写性及错误状态信息
//在这里查询可读性传入了 &rs,其他两个查询可写性及错误状态信息都是传入的NULL
//说明在这里调用者只检查套接字描述符集合rs里套接字的可读性
int res = select(mSocket + 1, &rs, NULL, NULL, &tv);

if (res == 1) {
//刚才只通过FD_SET(mSocket, &rs)向套接字描述符集合rs里添加了一个我们创建的套接字描述符mSocket
//所以select函数的返回值res为1说明,套接字描述符mSocket描述的套接口具有可读性
//调用MakeSocketBlocking(mSocket, true)函数阻塞该套接口,因为接下来需要从该套接口获取从服务端回应的消息
MakeSocketBlocking(mSocket, true);

//真正的从套接口获取服务端回应的消息是在receiveRTSPReponse函数里完成
//后续文章为大家介绍receiveRTSPReponse函数
bool success = receiveRTSPReponse();

//成功从该套接口获取到服务端回应的消息后调用MakeSocketBlocking(mSocket, false)函数将该套接口设置为非阻塞状态
MakeSocketBlocking(mSocket, false);

if (!success) {
// Something horrible, irreparable has happened.
flushPendingRequests();
return;
}
}

//调用postReceiveReponseEvent()函数再次开启这样一次处理,
//如此就形成了一个循环
postReceiveReponseEvent();
}


  小结:该循环的建立流程是:postReceiveReponseEvent ==> onReceiveResponse ==> postReceiveReponseEvent。这是一个设计技巧,是循环处理某些事务的机制,机制的原理就是形成一个循环调用圈。

  select函数的百科介绍:select(),确定一个或多个套接口的状态,本函数用于确定一个或多个套接口的状态,对每一个套接口,调用者可查询它的可读性、可写性及错误状态信息,用fd_set结构来表示一组等待检查的套接口,在调用返回时,这个结构存有满足一定条件的套接口组的子集,并且select()返回满足条件的套接口的数目。

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  RTSP