日韩美女乱婬AAA高清视频_国产色爱AV资源综合区_国产女同性黄网在线观看_欧美日韩一卡2卡3卡4卡新区乱码_俺来也俺也啪www色_精品久久久久久综合日本_99国内偷揿国产精品人妻_国产蜜芽剧果冻传媒_日本特级aaaaaaaa片_国产偷人妻精品一区二区在线

簡體中文

基于AVAPIs的文件下載

基于AVAPIs的文件下載流程 | TUTK P2P SDK 開發(fā)指南
基于AVAPIs的文件下載流程示意圖

圖 1:基于AVAPIs的文件下載整體流程示意圖

一、IO交互流程

文件下載的指令(相關(guān)內(nèi)容:AV幀信息通用定義)交互通過 avSendIOCtrl/avRecvIOCtrl 接口完成,分為文件列表查詢、下載請求、響應(yīng)三個關(guān)鍵階段,最終觸發(fā)通道創(chuàng)建和數(shù)據(jù)傳輸。

階段1:文件列表查詢

? APP 調(diào)用 avSendIOCtrl(IOCTRL_FILEMANAGER_FILE_LIST_REQ),傳入查詢條件(時間范圍、文件類型等,對應(yīng) stFileListReq 結(jié)構(gòu)體);

? 設(shè)備端通過 avRecvIOCtrl 接收請求,查詢符合條件的文件列表,通過 avSendIOCtrl(IOCTRL_FILEMANAGER_FILE_LIST_RESP) 回復(fù)(對應(yīng) stFileListResp 結(jié)構(gòu)體)。

階段2:下載請求發(fā)起

? 用戶在APP端選中待下載文件,APP 調(diào)用 avSendIOCtrl(IOCTRL_FILEMANAGER_FILE_DOWNLOAD_REQ),傳入待下載文件列表(對應(yīng) stFileDownloadReq 結(jié)構(gòu)體)。

階段3:下載響應(yīng)確認

? 設(shè)備端接收下載請求后,根據(jù)硬件性能(如CPU、帶寬)和軟件資源,自定義分配傳輸通道數(shù);

? 設(shè)備端通過 avSendIOCtrl(IOCTRL_FILEMANAGER_FILE_DOWNLOAD_RESP) 回復(fù)APP,包含分配的IOTC通道ID 和傳輸協(xié)議類型(此處為AVAPIs),對應(yīng) stFileDownloadResp 結(jié)構(gòu)體。

階段4:通道創(chuàng)建與數(shù)據(jù)傳輸

? APP 和設(shè)備端根據(jù)響應(yīng)中的 IOTC通道ID,分別創(chuàng)建對應(yīng)的AV通道;

? 通道創(chuàng)建成功后,設(shè)備端開始發(fā)送文件數(shù)據(jù),APP端接收并存儲數(shù)據(jù)。

階段5:通道銷毀

? 所有文件下載完成(檢測到 endFlag=1),APP 和設(shè)備端分別銷毀AV通道,釋放資源。

二、AV通道的創(chuàng)建和銷毀

通道創(chuàng)建需基于已建立的P2P會話(SID)和分配的IOTC通道ID,APP端與設(shè)備端的創(chuàng)建邏輯對稱,且必須開啟 resend=1(重傳模式)確保數(shù)據(jù)可靠傳輸。
(一)APP端(客戶端)通道操作
APP端作為文件接收方,通過 avClientStartEx 創(chuàng)建AV客戶端通道,avClientStop 銷毀通道。
int createDataChannelOfClientForDownload(int sid, int iotc_channel_id) {    AVClientStartInConfig in;    AVClientStartOutConfig out;    memset(&in,0, sizeof(in));    memset(&out,0, sizeof(out));    in.cb = sizeof(in);    in.iotc_session_id = sid;        // P2P會話ID(已建立的會話)    in.iotc_channel_id = iotc_channel_id; // 設(shè)備分配的IOTC通道ID    in.timeout_sec = 30;             // 連接超時時間(30秒)    in.resend = 1; //此處務(wù)必要開啟resend模式(確保數(shù)據(jù)可靠傳輸)    in.security_mode = AV_SECURITY_AUTO;    in.auth_type = AV_AUTH_PASSWORD;      in.account_or_identity = "camera account"; // 設(shè)備賬號,需跟設(shè)備端一致    in.password_or_token = "camera password"; // 設(shè)備密碼,需跟設(shè)備端一致    in.sync_recv_data = 0; // 0=異步接收數(shù)據(jù)(推薦)    in.dtls_cipher_suites = nullptr; // DTLS加密套件(默認NULL)    out.cb = sizeof(out);    return avClientStartEx(&in, &out); // 創(chuàng)建通道,返回AV通道索引(avIndex) }
說明:resend必須設(shè)為1,否則丟包時無法重傳導(dǎo)致文件損壞;SDK版本需區(qū)分認證類型,避免認證失敗。
void destoryDataChannelOfClient(int avIndex) {    if(avIndex < 0)        return ;        avClientStop(avIndex); // 銷毀AV通道,釋放資源 }
(二)設(shè)備端(服務(wù)端)通道操作
設(shè)備端作為文件發(fā)送方,通過 avServStartEx 創(chuàng)建AV服務(wù)端通道,avServStop 銷毀通道。
int createDataChannelOfDeviceForDownload(int sid, int iotc_channel_id) {    AVServStartInConfig avStartInConfig;    AVServStartOutConfig avStartOutConfig;        clearMemory(&avStartInConfig, sizeof(AVServStartInConfig));    clearMemory(&avStartOutConfig, sizeof(avStartOutConfig));    avStartInConfig.cb                    = sizeof(AVServStartInConfig);    avStartInConfig.iotc_session_id       = sid; // P2P會話ID    avStartInConfig.iotc_channel_id       = iotc_channel_id; // 分配的IOTC通道ID    avStartInConfig.timeout_sec           = 30; // 超時時間(30秒)    avStartInConfig.password_auth         = ExPasswordAuthCallBackFn; // 密碼認證回調(diào)(v3版本用)    avStartInConfig.server_type           = 0; // 服務(wù)端類型(默認0)    avStartInConfig.resend                = 1; // 必須開啟重傳模式    avStartInConfig.security_mode = AV_SECURITY_DTLS; // 啟用DTLS加密(安全傳輸)    //avStartInConfig.json_request = ExJsonRequest; // JSON請求回調(diào)(可選)        avStartOutConfig.cb = sizeof(AVServStartOutConfig);    return avServStartEx(&avStartInConfig, &avStartOutConfig); // 創(chuàng)建通道,返回AV通道索引 }
說明:security_mode設(shè)為AV_SECURITY_DTLS啟用加密傳輸,保護文件數(shù)據(jù)安全;password_auth回調(diào)用于v3版本的密碼校驗。
void destoryDataChannelOfDevice(int avIndex) {    if(avIndex < 0)        return ;    avServStop(avIndex); // 銷毀AV通道,釋放資源 }

三、數(shù)據(jù)傳輸流程

數(shù)據(jù)傳輸依賴 avSendFrameData(設(shè)備端發(fā)送)和 avRecvFrameData2(APP端接收)接口,文件信息通過 FRAMEINFO_FOR_UPLOAD_DOWNLOAD_t 結(jié)構(gòu)體攜帶(相關(guān)內(nèi)容:AV幀信息通用定義),傳輸單元為“文件信息+二進制數(shù)據(jù)”。
(一)設(shè)備端(發(fā)送方)數(shù)據(jù)發(fā)送
設(shè)備端按文件分幀讀取二進制數(shù)據(jù),搭配文件信息幀頭發(fā)送,支持多文件連續(xù)傳輸,處理丟包重傳(錯誤碼-20006)。
#define MAX_BUFFER_SIZE 10243 // 單次發(fā)送最大緩沖區(qū)大小(可根據(jù)實際調(diào)整) // 從文件讀取二進制數(shù)據(jù)(工具函數(shù)) int readBinaryDataFromFile(file f, char* buffer, size_t bufferSize) {    return f.read(buffer, bufferSize); } // 發(fā)送文件列表(核心函數(shù)) void sendFileList(void* arg) {    int avIndex = createDataChannelOfDeviceForDownload(sid, iotc_channel_id);    if(avIndex < 0){        printf("createDataChannelOfDeviceForDownload failed, error code:%d\n", avIndex);        return ;    }        foreach(auto f, files){ // 遍歷待發(fā)送文件列表        // 打開文件        f.open();        // 初始化文件信息幀頭        FRAMEINFO_FOR_UPLOAD_DOWNLOAD_t frmInfo = {0};        strcpy(frmInfo.fileName, f.name().c_str()); // 文件名(含擴展名)        frmInfo.fileSize = f.size(); // 文件總大?。ㄗ止?jié))                while(1){            char buffer[MAX_BUFFER_SIZE] = {0};            // 讀取文件數(shù)據(jù)            int readSize = readBinaryDataFromFile(f, buffer, MAX_BUFFER_SIZE);            if(readSize < MAX_BUFFER_SIZE){                if(readSize <= 0)                    break; // 讀取完畢,退出循環(huán)                // 若為文件列表中最后一個文件,設(shè)置結(jié)束標(biāo)志                if(f.isLastFileOfList()){                    frmInfo.endFlag = 1;                                    }            }                        frmInfo.frmSize = readSize; // 當(dāng)前幀數(shù)據(jù)大小            int ret = 0;                        // 發(fā)送數(shù)據(jù):遇-20006(丟包)則重傳            do{                ret = avSendFrameData(                    avIndex,                // AV通道索引                    buffer,                 // 二進制數(shù)據(jù)緩沖區(qū)                    readSize,               // 數(shù)據(jù)長度                    (const void*)&frmInfo, // 文件信息幀頭                    sizeof(FRAMEINFO_FOR_UPLOAD_DOWNLOAD_t) // 幀頭長度                );                if(ret < 0){                    if(ret == -20006){ // 丟包錯誤,等待后重傳                        msleep(20);                    } else { // 其他錯誤,退出發(fā)送                        break;                    }                }            } while(ret == -20006);            // 異常退出:關(guān)閉文件并銷毀通道            if(ret < 0){                printf("avSendFrameData error :%d\n", ret);                f.close();                goto LAB_END;            }                        // 最后一幀發(fā)送完成,退出當(dāng)前文件循環(huán)            if(frmInfo.endFlag){                break;            }        }        f.close(); // 關(guān)閉當(dāng)前文件    }    // 等待重傳緩沖區(qū)清空(避免數(shù)據(jù)殘留)    int i_count = 0;    while(i_count++ < 10*300){ // 最多等待30秒        float userate = avResendBufUsageRate(avIndex); // 獲取重傳緩沖區(qū)使用率        if(userate > 0.0){            msleep(100);        } else {            break; // 緩沖區(qū)為空,可安全銷毀通道        }    } LAB_END:    destoryDataChannelOfDevice(avIndex); // 銷毀通道 }
(二)APP端(接收方)數(shù)據(jù)接收
APP端循環(huán)接收數(shù)據(jù),解析幀頭信息,處理文件切換(新文件打開/舊文件關(guān)閉),驗證結(jié)束標(biāo)志,完成后關(guān)閉文件和通道。
#define MAX_BUFFER_SIZE 300*1024 // 接收緩沖區(qū)大小(建議大于發(fā)送端緩沖區(qū)) void recvDataAndSaveToLocalFile(void *arg) {    // 創(chuàng)建接收通道    int avIndex = createDataChannelOfClientForDownload(sid, iotc_channel_id);    if(avIndex < 0){        printf("createDataChannelOfClientForDownload failed\n");        return;    }    char buffer[MAX_BUFFER_SIZE];    string fileName;    uint fileSize;    uint dataSize;    int endFlag;    FRAMEINFO_FOR_UPLOAD_DOWNLOAD_t frmInfo;    int tmpInt1, tmpInt2, tmpInt3, tmpInt4;    uint frmNo;    file f; // 本地文件對象        // 循環(huán)讀取數(shù)據(jù)    while(1){        int ret = avRecvFrameData2(            avIndex,                // AV通道索引            buffer,                 // 接收緩沖區(qū)            MAX_BUFFER_SIZE,        // 緩沖區(qū)最大長度            &tmpInt1,               // 預(yù)留參數(shù)(忽略)            &tmpInt2,               // 預(yù)留參數(shù)(忽略)            (char*)&frmInfo,        // 接收文件信息幀頭            sizeof(FRAMEINFO_FOR_UPLOAD_DOWNLOAD_t), // 幀頭長度            &tmpInt3,               // 預(yù)留參數(shù)(忽略)            &frmNo                  // 幀序號(忽略)        );                if(ret < 0){            if(ret == AV_ER_DATA_NOREADY){ // 暫無數(shù)據(jù),短暫等待                msleep(5);                continue;            } else if(ret == AV_ER_INCOMPLETE_FRAME || ret == AV_ER_LOSED_THIS_FRAME){                printf("lost data, frameNo:%d\n", frmNo); // 幀不完整/丟失,繼續(xù)接收                continue;            } else { // 其他錯誤(如通道斷開),退出循環(huán)                printf("avRecvFrameData2 return error:%d\n", ret);                break;            }        }                // 處理文件切換:未打開文件→打開新文件;文件名變化→關(guān)閉舊文件,打開新文件        if(!f.isOpen()){            fileName = frmInfo.fileName;            f.setFileName(fileName);            if(!f.open(QIODevice::WriteOnly)){ // 以只寫模式打開文件                printf("open file failed:%s\n", fileName.toUtf8().data());                break;            }        } else {            if(fileName != frmInfo.fileName){ // 檢測到新文件                f.close(); // 關(guān)閉舊文件                fileName = frmInfo.fileName;                f.setFileName(fileName);                if(!f.open(QIODevice::WriteOnly)){                    printf("open file failed:%s\n", fileName.toUtf8().data());                    break;                }            }        }                // 寫入本地文件(ret為實際接收的數(shù)據(jù)長度)        f.write(buffer, ret);                // 檢測結(jié)束標(biāo)志:最后一個文件的最后一包,退出循環(huán)        if(frmInfo.endFlag){            printf("file download complete, fileName:%s\n", fileName.toUtf8().data());            break;        }    }    // 關(guān)閉本地文件    if(f.isOpen()){        f.close();    }    // 銷毀通道,釋放資源,建議收完最后一幀后延遲1s再關(guān)閉通道    destoryDataChannelOfClient(avIndex); }

四、結(jié)束標(biāo)志的判斷

結(jié)束標(biāo)志通過 FRAMEINFO_FOR_UPLOAD_DOWNLOAD_t 結(jié)構(gòu)體的 endFlag 字段判斷,規(guī)則如下:

? endFlag = 0:非最后一個文件的數(shù)據(jù)包,或最后一個文件的非最后一包數(shù)據(jù);

? endFlag = 1:僅當(dāng)所有待下載文件中,最后一個文件的最后一包數(shù)據(jù) 才設(shè)為1,用于標(biāo)識整個下載流程結(jié)束。

注意:多文件連續(xù)傳輸時,前序文件的最后一包 endFlag 仍為0,僅最后一個文件的最后一包設(shè)為1,避免APP端誤判提前關(guān)閉通道。

即刻開啟您的物聯(lián)網(wǎng)之旅

聯(lián)系解決方案專家
Kalay App
資訊安全白皮書
全球?qū)@季?/a>
解決方案
新聞動態(tài)
公司動態(tài)
行業(yè)資訊
媒體報道
永續(xù)發(fā)展
經(jīng)營者的話
社會參與
環(huán)境永續(xù)
公司治理

+86 755 27702549

7×24小時服務(wù)熱線

法律聲明 隱私權(quán)條款

關(guān)注“TUTK”

TUTK服務(wù)盡在掌握

? 2022 物聯(lián)智慧科技(深圳)有限公司版權(quán)所有粵ICP備14023641號
在線咨詢
掃一掃

TUTK服務(wù)盡在掌握

全國免費服務(wù)熱線
+86 755 27702549

返回頂部