void ARTSPConnection::performConnect(const sp<AMessage> &reply,
AString host, unsigned port) {
//传递来的参数reply消息的引用,此消息的消息名为"conn",消息的处理者是MyHandler
//调用gethostbyname(host.c_str()函数将AString类型表示的主机号转换成hostent类型的结构体,这是一个系统函数,没有深究,后面研究了的话会分享给大家
struct hostent *ent = gethostbyname(host.c_str());
if (ent == NULL) {
ALOGE("Unknown host %s", host.c_str());
//如果ent的值为NULL说明无法完成转换,在reply消息的"result"字段设置错误码-ENOENT
//该消息的消息名为"conn",消息的处理者是MyHandler,因此会在MyHandler::onMessageReceived的case "conn"处理分支处理
//在处理分支上会检查设置的"result"字段的错误码
reply->setInt32("result", -ENOENT);
reply->post();
//连接不成功,将状态设置为DISCONNECTED
mState = DISCONNECTED;
return;
}
//调用系统函数socket创建一个网络套机字,并将返回的套接字描述符赋值给mSocket成员变量
//关于系统函数socket,大家可以在网上查一下相关资料的介绍
mSocket = socket(AF_INET, SOCK_STREAM, 0);
if (mUIDValid) {
HTTPBase::RegisterSocketUserTag(mSocket, mUID,
(uint32_t)*(uint32_t*) "RTSP");
HTTPBase::RegisterSocketUserMark(mSocket, mUID);
}
//调用函数MakeSocketBlocking将创建的网络套接字设置为非阻塞状态,因为下面需要完成本地与主机的连接
MakeSocketBlocking(mSocket, false);
//创建一个sockaddr_in类型的结构体remote
//将remote结构体的sin_zero域内存清零,并设置相应的域
//关于sockaddr_in类型结构体的定义:
/*struct sockaddr_in
*{
* short sin_family;/*Address family一般来说AF_INET(地址族)PF_INET(协议族)*/
* unsigned short sin_port;/*Port number(必须要采用网络数据格式,普通数字可以用htons()函数转换成网络数据格式的数字)*/
* struct in_addr sin_addr;/*IP address in network byte order(Internet address)*/
* unsigned char sin_zero[8];/*Same size as struct sockaddr没有实际意义,只是为了 跟SOCKADDR结构在内存中对齐*/
*};
*/
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);
//调用系统函数connect来完成RTSP流的连接,返回值err标识连接的状态
int err = ::connect(
mSocket, (const struct sockaddr *)&remote, sizeof(remote));
//向reply消息设置"server-ip"字段,该字段的值是一个32位的整数
reply->setInt32("server-ip", ntohl(remote.sin_addr.s_addr));
if (err < 0) {
//系统函数connect的返回值err小于零说明没有成功连接,进行相应的处理
//这里不分析具体的错误处理流程
//需要注意的是,连接不成功,需要调用close(mSocket)函数来关闭创建的套接字
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 {
//系统函数connect的返回值err大于等于零说明成功连接
//设置"result"字段的值为OK,状态mState设置为CONNECTED状态
//mNextCSeq的值设置为1,表示从序列号从1开始接收数据
reply->setInt32("result", OK);
mState = CONNECTED;
mNextCSeq = 1;
//调用postReceiveReponseEvent()函数启动一个不断向服务端发送请求,接收服务端的响应并进行处里的这样一个循环
//具体的实现机制后续向大家介绍
postReceiveReponseEvent();
}
//将reply消息发送出去,对该消息的处理是在MyHandler::onMessageReceived的case "conn"分支
reply->post();
}
ARTSPConnection::performConnect函数完成RTSP流的连接
最新推荐文章于 2022-12-27 17:55:19 发布