赞
踩
最近在学习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);
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。