ARTSPConnection::performConnect函数完成RTSP流的连接

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();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值