前面我们分析到WifiDisplaySource会调用ANetworkSession的接口去创建一个socket,并在这个socket上监听是否有客户端的连接请求。先来看看Wifi Display规范的一些流程图:
从之前的一篇文章中,当ANetworkSession创建好RTSP的listen socket后,就会把它加入到selelct中等待对方的连接,那我们首先来看ANetworkSession的threadLoop方法:
void ANetworkSession::threadLoop() {
int res = select(maxFd + 1, &rs, &ws, NULL, NULL /* tv */);
{
Mutex::Autolock autoLock(mLock);
List<sp<Session> > sessionsToAdd;
for (size_t i = mSessions.size(); res > 0 && i-- > 0;) {
const sp<Session> &session = mSessions.valueAt(i);
int s = session->socket();
if (s < 0) {
continue;
}
if (FD_ISSET(s, &rs) || FD_ISSET(s, &ws)) {
--res;
}
if (FD_ISSET(s, &rs)) {
if (session->isRTSPServer() || session->isTCPDatagramServer()) {
struct sockaddr_in remoteAddr;
socklen_t remoteAddrLen = sizeof(remoteAddr);
int clientSocket = accept(
s, (struct sockaddr *)&remoteAddr, &remoteAddrLen);
if (clientSocket >= 0) {
status_t err = MakeSocketNonBlocking(clientSocket);
if (err != OK) {
} else {
in_addr_t addr = ntohl(remoteAddr.sin_addr.s_addr);
ALOGI("incoming connection from %d.%d.%d.%d:%d "
"(socket %d)",
(addr >> 24),
(addr >> 16) & 0xff,
(addr >> 8) & 0xff,
addr & 0xff,
ntohs(remoteAddr.sin_port),
clientSocket);
sp<Session> clientSession =
new Session(
mNextSessionID++,
Session::CONNECTED,
clientSocket,
session->getNotificationMessage());
clientSession->setMode(
session->isRTSPServer()
? Session::MODE_RTSP
: Session::MODE_DATAGRAM);
sessionsToAdd.push_back(clientSession);
}
} else {
ALOGE("accept returned error %d (%s)",
errno, strerror(errno));
}
}
}
while (!sessionsToAdd.empty()) {
sp<Session> session = *sessionsToAdd.begin();
sessionsToAdd.erase(sessionsToAdd.begin());
mSessions.add(session->sessionID(), session);
ALOGI("added clientSession %d", session->sessionID());
}
}
上面在selelct循环中,首先只有刚创建的RTSP的listen socket,接着如果有客户端的连接请求,就会跳出select语句,然后调用accept去接收对方的连接。接着会去创建一个新的Session会话,我们去看它的构造函数:
ANetworkSession::Session::Session(
int32_t sessionID,