QT 编程学习记录のUDP文件传输

最近在学习QT的网络编程,涉及UDP这块,动手写了一个基于UDP传输协议的文件发送和接收程序,其中涉及了一些QT控件的功能,也包含了文件操作。
UDP:是一种无连接,不可靠的传输层协议,在传输和接收之前不需要握手操作,建立套接字之后,发送端直接进行文件的读取和发送,而接收端循环检测是否有数据可读,可读就读取数据并写入新建的文件。
重点在于套接字的信号和槽的使用。
主要代码如下:
发送端:

void SendFileWidget::sendData(int port)
{
    if(isFileHead){ //发送文件头,包含文件信息
        QString msg = fileInfo.fileName() + "##" + QString::number(fileInfo.size());
        udpSocket->writeDatagram(msg.toUtf8(),QHostAddress("192.168.1.172"),port);
        isFileHead = false;
    }
    else{
        if(!file->atEnd()){
            QByteArray msg;
         msg = file->read(512);
         ui->listWidget->addItem(QString(msg));
         ui->listWidget->scrollToBottom();
         int length = udpSocket->writeDatagram( msg, QHostAddress("192.168.1.172"),port);
         sendCnt += length;
         ui->progressBar->setValue(sendCnt);
         qDebug() << QString::number(length);
        }
        else
        {
          ui->pushButton_send->setEnabled(true);
          udpSocket->writeDatagram( "OVER", 4, QHostAddress("192.168.1.172"),port);
          QMessageBox::information(this, "Succeed", "send succeed");
          return;
        }
    }
}

void SendFileWidget::on_pushButton_path_clicked()
{
    QString path = QFileDialog::getOpenFileName(this);
    ui->lineEdit_path->setText(path);
    fileInfo = QFileInfo(path);
    ui->pushButton_send->setEnabled(true);
}

void SendFileWidget::on_pushButton_send_clicked()
{
    if(ui->lineEdit_path->text().isEmpty())
    {
        QMessageBox::warning(this, "PATH", "the path is NULL");
        return;
    }
    bool ok;
    my_port = ui->lineEdit_port->text().toShort(&ok);
    if(!ok){
        QMessageBox::warning(this, "Port", "the port is NULL");
        return;
    }
    QString path = ui->lineEdit_path->text();
    file = new QFile(path);
    ok = file->open(QIODevice::ReadOnly);
    if(!ok){
        QMessageBox::warning(this, NULL, file->errorString());
        return;
    }
    ui->pushButton_send->setDisabled(true);
    ui->progressBar->setMaximum(file->size());
    udpSocket = new QUdpSocket(this);
    udpSocket->bind(QHostAddress::LocalHost, 7754);
    connect(udpSocket, SIGNAL(readyRead()), this, SLOT(ReadData()));
    sendData(my_port);
}

void SendFileWidget::ReadData()
{
    while(udpSocket->hasPendingDatagrams())
    {
        QByteArray datagram;
        QHostAddress host;
        quint16 port;
        datagram.resize(udpSocket->pendingDatagramSize());
        udpSocket->readDatagram(datagram.data(), datagram.size(), &host, &port);

        qDebug() << datagram;
        if(datagram == "OK"){
            qDebug() << "send ok";
            sendData(my_port);
        }
    }
}

接收端:

void RecvFileWidget::on_pushButton_path_clicked()
{
    QString path = QFileDialog::getOpenFileName(this);
    ui->lineEdit_path->setText(path);
    QFileInfo fileInfo = QFileInfo(path);
}

void RecvFileWidget::on_pushButton_recv_clicked()
{
    if(ui->lineEdit_path->text().isEmpty())
    {
        QMessageBox::warning(this, "PATH", "the path is NULL");
        return;
    }
    int port;
    bool ok;
    port = ui->lineEdit_port->text().toShort(&ok);
    if(!ok){
        QMessageBox::warning(this, "Port", "the port is NULL");
        return;
    }
    ui->pushButton_recv->setDisabled(true);
    udpSocket = new QUdpSocket(this);
    connect(udpSocket, SIGNAL(readyRead()),this, SLOT(slotReadData()));
    ok = udpSocket->bind(QHostAddress::AnyIPv4, port, QUdpSocket::ReuseAddressHint);
    if(!ok){
        QMessageBox::warning(this, "Failure", udpSocket->errorString());
        return;
    }
    file.setFileName(ui->lineEdit_path->text());
    if(!file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Unbuffered))
    {
        QMessageBox::warning(this, "create", "create file error");
        return;
    }
}

void RecvFileWidget::slotReadData()
{
    while(udpSocket->hasPendingDatagrams())
    {
        QByteArray datagram;
        QHostAddress host;
        quint16 port;
        datagram.resize(udpSocket->pendingDatagramSize());
        int length = udpSocket->readDatagram(datagram.data(), datagram.size(), &host, &port);

        if(isFileHead){
            QStringList msgs = QString(datagram).split("##");
            qDebug() << msgs;
            if(msgs.count() != 2){
                QMessageBox::warning(this, "Error", "Receive FileHead error");
            }
            QString fileLength = msgs.at(1);
            int fileSize = fileLength.toInt();
            ui->progressBar->setMaximum(fileSize);
            isFileHead = false;
            udpSocket->writeDatagram("OK", 2, host, 7754);
            continue;
        }
        if(datagram == "OVER"){
            QMessageBox::information(this, "success", "Recieve File Success");
            ui->pushButton_recv->setEnabled(true);
            return;
        }
        recvCnt += length;
        ui->progressBar->setValue(recvCnt);
        file.write(datagram.data(),datagram.size());
        udpSocket->writeDatagram("OK", 2, host, 7754);
        ui->listWidget->addItem(QString(datagram));
         ui->listWidget->scrollToBottom();
      //  qDebug() << datagram << " " << host.toString() << QString::number(port);
    }
}
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值