Qt编写的文件传输工具

news2024/12/15 12:52:55

使用QT编写的文件传输工具

  • 文件传输工具
  • 通过发送udp广播消息将IP广播给其他开启该程序的局域网机器

文件传输工具

通过发送udp广播消息将IP广播给其他开启该程序的局域网机器

收到的广播消息可以显示在IP地址列表中,点击IP地址可以自动填充到IP地址栏内

选择文件后点击发送可以发送给指定IP,并能在传输过程中显示进度

默认端口6001。目前不支持修改,修改端口会导致网络连接失败。

资源链接:https://download.csdn.net/download/codears/90117330?spm=1001.2014.3001.5503

界面比较简洁:
FileSender界面
部分代码如下:
udp发送广播消息

void Client::SendUDPMsg() {
    int ret = 0;
    // 设置广播地址
    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;
    }
}

启动udp服务:

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;
}

启动tcp服务用于接收文件和发送文件:

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发送文件:

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("创建目录[%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);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2259938.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【潜意识Java】深入理解 Java 面向对象编程(OOP)

目录 什么是面向对象编程&#xff08;OOP&#xff09;&#xff1f; 1. 封装&#xff08;Encapsulation&#xff09; Java 中的封装 2. 继承&#xff08;Inheritance&#xff09; Java 中的继承 3. 多态&#xff08;Polymorphism&#xff09; Java 中的多态 4. 抽象&…

PWM调节DCDC参数计算原理

1、动态电压频率调整DVFS SOC芯片的核电压、GPU电压、NPU电压、GPU电压等&#xff0c;都会根据性能和实际应用场景来进行电压和频率的调整。 即动态电压频率调整DVFS&#xff08;Dynamic Voltage and Frequency scaling&#xff09;&#xff0c;优化性能和功耗。 比如某SOC在…

OpenCV相关函数

一、二值化函数&#xff08;threshold&#xff09; 功能&#xff1a;将灰度图像转换为二值图像&#xff0c;通常用于图像分割。通过设置阈值&#xff0c;把图像中低于阈值的像素设为0&#xff0c;高于阈值的像素设为1。 参数&#xff1a; src&#xff1a;输入图像。 thresh&a…

bean后处理器的作用

这是beanFactory中常见的一些后处理器&#xff1a; 其中这俩个属于bean后处理器&#xff1a; internalAutowiredAnnotationProcessor解析Autowired、Value internalCommonAnnotationProcessor解析Resource、PostConstruct、PreDestroy Bean后处理器的作用&#xff1a;为Bean…

YOLOv11融合[CVPR2024]Starnet中的star block取模块

YOLOv11v10v8使用教程&#xff1a; YOLOv11入门到入土使用教程 YOLOv11改进汇总贴&#xff1a;YOLOv11及自研模型更新汇总 《Rewrite the Stars》 一、 模块介绍 论文链接&#xff1a;https://arxiv.org/abs/2403.19967 代码链接&#xff1a;https://github.com/ma-xu/Rewri…

日常灵感:听劝是一种天赋

希望这段分享能给你提供一些新的角度&#xff0c;让你在自己的工作和生活中更好地利用这份“听劝”的天赋&#xff01; 父与子的救赎&#xff1a;听劝的天赋 学霸爸爸李先生是一个典型的"别人家的父母"。 他从小就是学霸&#xff0c;凭借过硬的学习能力从重点高中一…

The Rise and Potential of Large Language ModelBased Agents:A Survey---讨论

讨论 论法学硕士研究与Agent研究的互利性 近年来&#xff0c;随着激光诱导金属化技术的发展&#xff0c;激光诱导金属化与化学剂交叉领域的研究取得了长足的进步&#xff0c;促进了这两个领域的发展。在此&#xff0c;我们期待着LLM研究和Agent研究相互提供的一些益处和发展机…

React 第十六节 useCallback 使用详解注意事项

useCallback 概述 1、useCallback 是在React 中多次渲染缓存函数的 Hook&#xff0c;返回一个函数的 memoized的值&#xff1b; 2、如果多次传入的依赖项不变&#xff0c;那么多次定义的时候&#xff0c;返回的值是相同的,防止频繁触发更新&#xff1b; 3、多应用在 父组件为函…

Transformer: Attention Is All You Need (2017) 翻译

论文&#xff1a;Attention Is All You Need 下载地址如下: download: Transformer Attention Is All you need Attention Is All You Need 中文 《Attention Is All You Need》是《Transformer》模型的开创性论文&#xff0c;提出了一种全新的基于注意力机制的架构&#xf…

Git-分支(branch)常用命令

分支 我们在做项目开发的时候&#xff0c;无论是软件项目还是其他机械工程项目&#xff0c;我们为了提高效率以及合理的节省时间等等原因&#xff0c;现在都不再是线性进行&#xff0c;而是将一个项目抽离出诸进行线&#xff0c;每一条线在git中我们就叫做分支&#xff0c;bran…

【AIGC进阶-ChatGPT提示词副业解析】反向心理学在沟通中的运用:激将法的艺术

引言 在日常沟通和管理中&#xff0c;直接的表达方式并不总能达到预期效果。反向心理学&#xff0c;特别是其中的激将法&#xff0c;作为一种独特的沟通技巧&#xff0c;往往能在看似消极的表达中激发出积极的反应。本文将深入探讨反向心理学中激将法的运用技巧、实施策略及其…

360智脑张向征:共建可信可控AI生态 应对大模型安全挑战

发布 | 大力财经 人工智能的加速发展&#xff0c;有力推动了社会的数智化转型&#xff1b;与此同时&#xff0c;带来的相关安全风险也日益凸显。近日&#xff0c;在北京市举办的通明湖人工智能开发与应用大会上&#xff0c;360智脑总裁张向征以“大模型安全研究与实践”为主题&…

lc46全排列——回溯

46. 全排列 - 力扣&#xff08;LeetCode&#xff09; 法1&#xff1a;暴力枚举 总共n!种全排列&#xff0c;一一列举出来放入list就行&#xff0c;关键是怎么去枚举呢&#xff1f;那就每次随机取一个&#xff0c;然后删去这个&#xff0c;再从剩下的数组中继续去随机选一个&a…

在线设计平台:Axure新手的在线设计助手

Axure是一款在产品设计、用户体验和交互设计领域广泛使用的强大原型设计工具。它使设计师和产品经理能够迅速构建高保真原型&#xff0c;验证设计和功能&#xff0c;并进行用户测试。结合在线设计平台的协作特性&#xff0c;团队可以更高效地创建、分享和优化原型&#xff0c;加…

Burp与小程序梦中情缘

前言 在日常渗透工作中&#xff0c;有时需要对微信小程序进行抓包渗透&#xff0c;通过抓包&#xff0c;我们可以捕获小程序与服务器之间的通信数据&#xff0c;分析这些数据可以帮助我们发现潜在的安全漏洞&#xff0c;本文通过讲述三个方法在PC端来对小程序抓包渗透 文章目…

gpu硬件架构

1.简介 NVIDIA在视觉计算和人工智能&#xff08;AI&#xff09;领域处于领先地位&#xff1b;其旗舰GPU已成为解决包括高性能计算和人工智能在内的各个领域复杂计算挑战所不可或缺的。虽然它们的规格经常被讨论&#xff0c;但很难掌握各种组件的清晰完整的图景。 这些GPU的高性…

SpringCloud集成sleuth和zipkin实现微服务链路追踪

文章目录 前言技术积累spring cloud sleuth介绍zipkin介绍Zipkin与Sleuth的协作 SpringCloud多模块搭建Zipkin Server部署docker pull 镜像启动zipkin server SpringCloud 接入 Sleuth 与 Zipkinpom引入依赖 (springboot2.6)appilication.yml配置修改增加测试链路代码 调用微服…

OBS + SRS:打造专业级直播环境的入门指南

OBS SRS&#xff1a;打造专业级直播环境的入门指南 1. OBS简介2. OBS核心功能详解2.1 场景&#xff08;Scenes&#xff09;管理2.2 源&#xff08;Sources&#xff09;控制2.3 混音器功能2.4 滤镜与特效2.5 直播控制面板 3. OBS推流到SRS服务器配置指南3.1 环境准备3.2 OBS推流…

Ubuntu K8s

https://serious-lose.notion.site/Ubuntu-K8s-d8d6a978ad784c1baa2fc8c531fbce68?pvs74 2 核 2G Ubuntu 20.4 IP 172.24.53.10 kubeadmkubeletkubectl版本1.23.01.23.01.23.0 kubeadm、kubelet 和 kubectl 是 Kubernetes 生态系统中的三个重要组件 kubeadm&#xff1a; 主…

前端(六)浮动流

浮动流 文章目录 浮动流一、标准流二、浮动流 一、标准流 所谓网页布局就是网页排版的方式&#xff0c;css中有三种网页布局的方式&#xff1a;标准流、浮动流和定位流。 标准流也称文档流&#xff0c;这是浏览器默认的排版方式。标准流中网页的元素会按从左往右、从上往下的…