最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Qt編寫的文件傳輸工具

 更新時(shí)間:2024年12月12日 10:13:19   作者:codears  
這篇文章主要為大家詳細(xì)介紹了如何基于Qt編寫一個(gè)文件傳輸工具,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

文件傳輸工具

通過發(fā)送udp廣播消息將IP廣播給其他開啟該程序的局域網(wǎng)機(jī)器

收到的廣播消息可以顯示在IP地址列表中,點(diǎn)擊IP地址可以自動(dòng)填充到IP地址欄內(nèi)

選擇文件后點(diǎn)擊發(fā)送可以發(fā)送給指定IP,并能在傳輸過程中顯示進(jìn)度

默認(rèn)端口6001。目前不支持修改,修改端口會(huì)導(dǎo)致網(wǎng)絡(luò)連接失敗。

界面比較簡潔:

部分代碼如下:

udp發(fā)送廣播消息

void Client::SendUDPMsg() {
    int ret = 0;
    // 設(shè)置廣播地址
    struct sockaddr_in client;
    memset(&client, 0, sizeof(client));
    client.sin_family = AF_INET;
    client.sin_port = htons(g_udpServerPort);
    client.sin_addr.s_addr = inet_addr("255.255.255.255");
    int len = sizeof(SOCKADDR);

    hostent* host = gethostbyname(g_serverHost.toStdString().c_str());
    QString msg = QString("broadcast|%1").arg(host->h_name);
    ret = sendto(m_udpClientSocket, msg.toStdString().c_str(), msg.length(), 0, (SOCKADDR*)&client, len);
}

udp接收消息:

void Client::RecvUDPMsg() {
    int ret = 0;
    struct sockaddr_in client;
    memset(&client, 0, sizeof(client));
    int len = sizeof(SOCKADDR);

    char buff[BUFF_SIZE] = {0};
    ret = recvfrom(m_udpServerSocket, buff, BUFF_SIZE, 0, (SOCKADDR*)&client, &len);
    QString host(inet_ntoa(client.sin_addr));
    if (m_localIPv4List.indexOf(host) == -1 && m_knownHosts.indexOf(host) == -1) {
        qDebug() << __FUNCTION__ << "new host:" << host;
        m_knownHosts.push_back(host);
        (static_cast<Work*>(m_pParent))->NewHost(host);
    } else {
        return;
    }
}

啟動(dòng)udp服務(wù):

bool Client::StartUdpServer(NetworkParams& params) {
    QString host = params.serverIP;
    m_hostnm = gethostbyname(host.toStdString().c_str());
    if (m_hostnm != (struct hostent*)0) {
        qDebug() << __FUNCTION__ << "hostname:" << m_hostnm->h_addrtype << " addr:" << m_hostnm->h_name;
    }

    int ret = 0;
    if ((m_udpServerSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
        return false;
    }
    int port = params.serverPort;

    memset(&m_sockAddr, 0, sizeof(m_sockAddr));
    m_sockAddr.sin_family = AF_INET;
    m_sockAddr.sin_port = htons(port);
    //m_sockAddr.sin_addr.S_un.S_addr= inet_addr(host.toStdString().c_str());
    m_sockAddr.sin_addr.s_addr = INADDR_ANY;
    ret = bind(m_udpServerSocket, (const struct sockaddr*)&m_sockAddr, sizeof(m_sockAddr));
    if (ret < 0) {
        return false;
    } else {
    }

    GetIPv4List();
    return true;
}

啟動(dòng)tcp服務(wù)用于接收文件和發(fā)送文件:

bool Client::StartTcpServer(NetworkParams& params) {
    if (!m_bSocketClosed) {
        return true;
    }
    QString host = params.serverIP;
    m_hostnm = gethostbyname(host.toStdString().c_str());
    if (m_hostnm != (struct hostent*)0) {
        qDebug() << __FUNCTION__ << "hostname:" << m_hostnm->h_addrtype << " addr:" << m_hostnm->h_name;
    }

    int ret = 0;
    if ((m_tcpServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
        return false;
    }
    int port = params.serverPort;
    memset(&m_sockAddr, 0, sizeof(struct sockaddr_in));
    m_sockAddr.sin_family = AF_INET;
    m_sockAddr.sin_addr.s_addr = INADDR_ANY;
    m_sockAddr.sin_port = htons(port);
    ret = bind(m_tcpServerSocket, (const struct sockaddr*)&m_sockAddr, sizeof(m_sockAddr));
    if (ret < 0) {
        return false;
    } else {
        qDebug() << __FUNCTION__ << "bind success port:" << port;
    }

    if (listen(m_tcpServerSocket, 512)) {
        return false;
    }
    return true;
}

通過tcp發(fā)送文件:

bool Client::SendFile(QString strFullFilePath, QString strUserName) {
    if (strFullFilePath.isEmpty() || strUserName.isEmpty()) {
        return false;
    }
    strFullFilePath = strFullFilePath.replace("\\", "/");

    QString fileName = strFullFilePath.mid(strFullFilePath.lastIndexOf("/") + 1);
    QFile f(strFullFilePath);
    if (!f.exists()) {
        return false;
    }
    if (!f.open(QIODevice::ReadOnly)) {
        return false;
    }
    f.seek(SEEK_SET);
    quint64 fileSize = f.size();

    char chBuff[BUFF_SIZE] = {0};
    memset(chBuff, 0, BUFF_SIZE);

    QString s = QString("upload|%1|%2|%3|donotremove").arg(fileName).arg(fileSize).arg(strUserName);
    strcpy(chBuff, s.toStdString().c_str());
    send(m_iClientSocket, chBuff, strlen(chBuff) + 1, 0);

    quint64 sendSize = 0;
    NetworkParams params;
    params.totalSize = fileSize;
    while (sendSize < fileSize) {
        memset(chBuff, 0, BUFF_SIZE);
        qint64 iRead = f.read(chBuff, BUFF_SIZE);
        if (iRead < 0) {
            f.close();
            return false;
        }

        int iSend = send(m_iClientSocket, chBuff, iRead, 0);
        if (iSend < 0) {
            f.close();
            return false;
        }
        int temp = iRead;
        while (iSend < temp) {
            iSend = send(m_iClientSocket, chBuff + iSend, temp - iSend, 0);
            if (iSend < 0) {
                f.close();
                return false;
            }
            temp = temp - iSend;
        }

        sendSize += iSend;
        f.seek(sendSize);
        params.recved = sendSize;
        (static_cast<Work*>(m_pParent))->UpdateProgress(params);
    }

    f.close();
    closesocket(m_iClientSocket);
    m_bSocketClosed = true;
}

通過tcp接收文件:

bool Client::RecvFile() {
    SOCKET clientSock = NULL;
    struct sockaddr in_addr = {0};
    int addrLen = sizeof(in_addr);
    clientSock = accept(m_tcpServerSocket, (struct sockaddr*)&in_addr, &addrLen);

    if (clientSock == SOCKET_ERROR) {
        return false;
    }

    ssize_t len = 0;
    char buff[BUFF_SIZE] = {0};
    len = recv(clientSock, buff, sizeof(buff), 0);//1. get filename and client ip
    if (len <= 0) {
        return false;
    }

    QString fileNameAndClientIP(buff);//upload|filename|filesize|hostname
    QStringList sl = fileNameAndClientIP.split("|");
    if (sl.length() < 3) {
        return false;
    }

    QString fullFilePath = APPLICATION_DIR + "/" + sl.at(3);
    QDir d(fullFilePath);
    if (!d.exists()) {
        if (!d.mkdir(fullFilePath)) {
            ((Work*)m_pParent)->WarnMsg(QString("創(chuàng)建目錄[%1]失敗").arg(fullFilePath));
            return false;
        }
    }

    qlonglong fileSize = sl.at(2).toLongLong();
    QString fullName = fullFilePath + "/" + sl.at(1);
    QFile f(fullName);
    if (!f.open(QFile::ReadWrite)) {
        ((Work*)m_pParent)->WarnMsg(QString("打開文件:%1失敗").arg(fullName));
        return false;
    }
    qlonglong recvLen = 0;
    NetworkParams params;
    params.totalSize = fileSize;
    while (recvLen < fileSize) {
        memset(buff, 0, sizeof(buff));
        len = recv(clientSock, buff, sizeof(buff), 0);
        if (len <= 0) {
            break;
        }
        recvLen += len;
        f.write(buff, len);
        params.recved = recvLen;
        (static_cast<Work*>(m_pParent))->UpdateProgress(params);
    }
    f.close();
    closesocket(clientSock);
    (static_cast<Work*>(m_pParent))->ReceivedFile(fullName);
}

以上就是基于Qt編寫的文件傳輸工具的詳細(xì)內(nèi)容,更多關(guān)于Qt編寫文件傳輸?shù)馁Y料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • c++異常處理機(jī)制示例及詳細(xì)講解

    c++異常處理機(jī)制示例及詳細(xì)講解

    本篇文章主要是對(duì)c++異常處理機(jī)制示例進(jìn)行了介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助
    2014-02-02
  • C語言詳解如何實(shí)現(xiàn)順序棧

    C語言詳解如何實(shí)現(xiàn)順序棧

    順序棧,就是用一組地址連續(xù)的存儲(chǔ)單元來存放棧元素,然后用一個(gè)棧結(jié)構(gòu)去維護(hù)一個(gè)棧。在C中,可用動(dòng)態(tài)開辟的數(shù)組去表示,維護(hù)的棧結(jié)構(gòu)需要有一個(gè)棧底和一個(gè)棧頂指針
    2022-04-04
  • C 語言二叉樹幾種遍歷方法詳解及實(shí)例

    C 語言二叉樹幾種遍歷方法詳解及實(shí)例

    這篇文章主要介紹了C 語言二叉樹幾種遍歷方法詳解及實(shí)例的相關(guān)資料,二叉樹在數(shù)據(jù)結(jié)構(gòu)當(dāng)中是非常重要的知識(shí)要點(diǎn),這里對(duì)二叉樹進(jìn)行了總結(jié),需要的朋友可以參考下
    2017-01-01
  • C語言 全局變量和局部變量詳解及實(shí)例

    C語言 全局變量和局部變量詳解及實(shí)例

    這篇文章主要介紹了C語言 全局變量和局部變量詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • C語言實(shí)現(xiàn)鏈表貪吃蛇

    C語言實(shí)現(xiàn)鏈表貪吃蛇

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)鏈表貪吃蛇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • C語言如何實(shí)現(xiàn)翻轉(zhuǎn)字符串中的單詞

    C語言如何實(shí)現(xiàn)翻轉(zhuǎn)字符串中的單詞

    這篇文章主要介紹了C語言如何實(shí)現(xiàn)翻轉(zhuǎn)字符串中的單詞,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • C++中新手容易犯的十種編程錯(cuò)誤匯總

    C++中新手容易犯的十種編程錯(cuò)誤匯總

    一段C語言代碼,在編譯、鏈接和運(yùn)行的各個(gè)階段都可能會(huì)出現(xiàn)問題,下面這篇文章主要給大家介紹了關(guān)于C++中新手容易犯的十種編程錯(cuò)誤的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • C++實(shí)現(xiàn)循環(huán)隊(duì)列

    C++實(shí)現(xiàn)循環(huán)隊(duì)列

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)循環(huán)隊(duì)列,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-01-01
  • C++?自增自減運(yùn)算符的實(shí)現(xiàn)示例

    C++?自增自減運(yùn)算符的實(shí)現(xiàn)示例

    本文主要介紹了C++?自增自減運(yùn)算符的實(shí)現(xiàn)示例,自增和自減運(yùn)算符在C++中主要用于循環(huán)語句中,使循環(huán)變量的值自動(dòng)+1或者-1,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-08-08
  • C語言數(shù)據(jù)結(jié)構(gòu)之棧和隊(duì)列的實(shí)現(xiàn)及應(yīng)用

    C語言數(shù)據(jù)結(jié)構(gòu)之棧和隊(duì)列的實(shí)現(xiàn)及應(yīng)用

    棧和隊(duì)列是一種數(shù)據(jù)結(jié)構(gòu),只規(guī)定了性質(zhì),并沒有規(guī)定實(shí)現(xiàn)方式。本文將以順序結(jié)構(gòu)實(shí)現(xiàn)棧,鏈表方式實(shí)現(xiàn)隊(duì)列,感興趣的小伙伴快跟隨小編一起學(xué)習(xí)一下吧
    2022-08-08

最新評(píng)論

香港 | 凤山县| 冷水江市| 乾安县| 汉寿县| 宜都市| 西乌珠穆沁旗| 庆城县| 淮北市| 徐闻县| 营山县| 隆回县| 宣恩县| 进贤县| 秀山| 西昌市| 怀来县| 开远市| 固原市| 常山县| 荔浦县| 新宁县| 治多县| 渑池县| 寻乌县| 汨罗市| 安顺市| 临汾市| 黄陵县| 天气| 宁津县| 宁德市| 黄山市| 波密县| 南皮县| 凤山市| 金堂县| 信阳市| 康马县| 两当县| 湘乡市|