tcp文件传输(udp发送消息确定是否接收)
来源:互联网 发布:计算型材米重的软件 编辑:程序博客网 时间:2024/05/19 01:10
原文链接 http://blog.bccn.net/liYX9553/61129
dialog.h:
#ifndef DIALOG_H#define DIALOG_H #include <QDialog>#include <QTime> class QTcpServer;class QFile;class QTcpSocket;class QUdpSocket; namespace Ui {class Dialog;} class Dialog : public QDialog{ Q_OBJECT public: explicit Dialog(QWidget *parent = 0); ~Dialog(); void initser();// 初始化服务器。 private: Ui::Dialog *ui; qint16 tport; qint16 uport; qint16 u2port; qint64 totalBytes; qint64 writeBytes; qint64 tobeWriteBytes; qint64 payloadSize;//被初始化为第一个常量。 QByteArray outBlock; QTcpSocket *clintcon; QUdpSocket *udpSocket; QTcpServer *tser; QString fileName; QString theFileName; QFile *locFile; QTime time;protected: void SendFileName(QString fileName); QString getIP();private slots: void sendMsg(); void updClintProgress(qint64 numBytes); void getFileName(QString name); void refused();//关闭服务器。 void on_sCloseBtn_clicked(); void on_sOpenBtn_clicked(); void on_sSendBtn_clicked(); signals: void sendFileName(QString fileName);}; #endif // DIALOG_H
#include "dialog.h"#include "ui_dialog.h"#include <QFile>#include <QDebug>#include <QMessageBox>#include <QFileDialog>#include <QTcpServer>#include <QTcpSocket>#include <QNetworkInterface>#include "QObject"#include <QUdpSocket>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include <qtcpserver.h> Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog){ ui->setupUi(this); udpSocket = new QUdpSocket(this); uport = 8888; u2port = 7777; udpSocket->bind(u2port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint); connect(udpSocket, SIGNAL(readyRead()), this, SLOT(refused())); //sendMessage(NewParticipant); tport = 6666; tser = new QTcpServer(this); connect(tser,SIGNAL(newConnection()),this,SLOT(sendMsg())); connect(this,SIGNAL(sendFileName(QString)),this,SLOT(getFileName(QString))); initser();} Dialog::~Dialog(){ delete ui;}void Dialog::initser()//初始化服务器。{ totalBytes = 0; tobeWriteBytes = 0; writeBytes = 0; ui->sOpenBtn->setEnabled(true);//open按钮可用 ui->sSendBtn->setEnabled(false);//发送按钮不可用 ui->label_2->setText("请选择要发送的文件"); tser->close();}void Dialog::refused()//关闭服务器。{ tser->close(); ui->label_2->setText(tr("对方拒绝接收!"));}//发送文件void Dialog::sendMsg(){ qDebug() << "--------sendMsg start-----------" ; ui->sSendBtn->setEnabled(false);//设置按钮不可用 clintcon = tser->nextPendingConnection();//获取一个已经连接tcp套接字。 connect(clintcon,SIGNAL(bytesWritten(qint64)),this,SLOT(updClintProgress(qint64))); ui->label_2->setText(tr("开始传送文件 %1!").arg(theFileName)); locFile = new QFile(fileName);//只读方式打开文档 if(!locFile->open((QFile::ReadOnly))){ QMessageBox::warning(this,tr(""),tr("无法读取文件%1:\n %2").arg(fileName).arg(locFile->errorString())); return; } totalBytes = locFile->size();//文件的总字节数。 qDebug() << "fileTotalBytes:" << totalBytes; QDataStream sendOut(&outBlock,QIODevice::WriteOnly); sendOut.setVersion(QDataStream::Qt_4_7); time.start(); QString curFile = fileName.right(fileName.size() - fileName.lastIndexOf('/') -1 );//待发送文件名。 qDebug() << "curFile:" << curFile; sendOut << qint64(0) << qint64(0) << curFile; totalBytes += outBlock.size();//文件名大小信息+实际文件大小。 sendOut.device()->seek(0);//设置文件指针从0开始 sendOut << totalBytes << qint64((outBlock.size() - sizeof(qint64)*2)); tobeWriteBytes = totalBytes - clintcon->write(outBlock);//发送缓存区的数据,同时修改待发送的数据长度。 qDebug() << "tobeWriteBytes:" << tobeWriteBytes; qDebug() << "outBlock:" << outBlock; outBlock.resize(0);} void Dialog::on_sCloseBtn_clicked(){ if(tser->isListening()){ tser->close();//当tcp正在监听时,关闭tcp服务器端应用,即按下close键时就不监听tcp请求了 if(locFile->isOpen()){ locFile->close(); } clintcon->abort();//Socket::终止当前的连接,禁止写入缓存区。 } close();} void Dialog::on_sOpenBtn_clicked(){ fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "/home" );//tr("Images (*.png *.xpm *.jpg *.txt *.gz)") //fileName = QFileDialog::getOpenFileName(this); if(theFileName.isEmpty()){ theFileName = fileName.right(fileName.size() - fileName.lastIndexOf('/') - 1); ui->label_2->setText(tr("要发送的文件为:%1").arg(theFileName)); qDebug() << "thefilename:" << theFileName; } qDebug() << "fileName:" << fileName; ui->sSendBtn->setEnabled(true);} void Dialog::on_sSendBtn_clicked(){ qint8 a; a = tser->listen(QHostAddress::Any,tport); if(!a){ qDebug() << tser->errorString(); close(); } qDebug() << a; ui->label_2->setText(tr("等待对方接收....")); emit sendFileName(theFileName); qDebug() << "-----emit- success!------"; ui->sSendBtn->setEnabled(false);}//进度条修改进度。void Dialog::updClintProgress(qint64 numBytes){ qDebug() << "udpClintProgress start...."; qApp->processEvents(); //qDebug() << "writeBytes1:"<< writeBytes; //writeBytes += (int)numBytes; //qDebug() << "writeBytes2:" << writeBytes; if(tobeWriteBytes > 0){//没发送完。 outBlock = locFile->read(qMin(tobeWriteBytes,payloadSize));//每次最多发送64k大小。 tobeWriteBytes -= (int)clintcon->write(outBlock); writeBytes += (totalBytes - tobeWriteBytes);//已经发送了的。 outBlock.resize(0); }else { locFile->close(); } ui->progressBar->setMaximum(totalBytes); ui->progressBar->setValue(writeBytes); float useTime = time.elapsed(); double speed = writeBytes/useTime*1000000; ui->label_2->setText(tr("(%1 m/s)").arg(speed)); qDebug() << "writeBytes:"<< writeBytes; qDebug() << "totalBytes:" << totalBytes; if(writeBytes == totalBytes){ locFile->close(); tser->close(); ui->label_2->setText(tr("文件:%1发送成功!").arg(theFileName)); } }//获取文件名void Dialog::getFileName(QString name){ qDebug() << "------1getFileName--------" << name; theFileName = name; //qDebug() << "fileNamesize" << strlen(fileName); SendFileName(theFileName);}//发送文件名void Dialog::SendFileName(QString fileName){ QByteArray data; QDataStream out(&data, QIODevice::WriteOnly); QString address,clientaddr; address = getIP(); //clientaddr = getIP(); //QString clientAddress = ui->userTableWidget->item(row, 2)->text();//(row,,2)为ip地址 out << address << fileName;//发送本地ip,所发送的文件名 qDebug() << "SendFileName :" << fileName; qDebug() << "server IP:" << address; int a= udpSocket->writeDatagram(data,data.length(),QHostAddress::Broadcast, uport);//向8888端口广播 qDebug() << "a" << a;}//获取IPQString Dialog::getIP(){ QList<QHostAddress> list = QNetworkInterface::allAddresses(); foreach (QHostAddress address, list) { if(address.protocol() == QAbstractSocket::IPv4Protocol){ if(address.toString().contains("192.168.1")||address.toString().contains("127.0")) continue; return address.toString(); } } return 0;}
client.h
#ifndef DIALOG_H#define DIALOG_H #include <QDialog>#include <QHostAddress>#include <QFile>#include <QTime>#include <QDebug>#include <QMessageBox>#include"thread.h"enum MessageType{FileName, refuse};class QTcpSocket;class QUdpSocket;namespace Ui {class Dialog;} class Dialog : public QDialog{ Q_OBJECT public: explicit Dialog(QWidget *parent = 0); ~Dialog(); void setHostaddr(QHostAddress addr); //获取主机ip void setFileName(QString FileName); //获取文件保存路径 void reciveFileNmae();private slots: void on_cCancelBtn_clicked(); void on_cClosebtn_clicked(); protected: void SendRefuse(MessageType type); void closeEvent(QCloseEvent *); void hansPendingFile(QString serAddress,QString fileName); QString getIP();private: Thread *b; Ui::Dialog *ui; QUdpSocket *udpSocket; QTcpSocket *cClint; QHostAddress hostAddr; qint16 tport; qint16 uport; qint16 u2port; quint16 blockSize; qint64 totalBytes; qint64 recevBytes; qint64 fileNameSize; QString FileName; QString *SerAdress; QFile *locFile; //要接收的文件 QByteArray inBlock; //缓存一次接收的数据 QTime Time;private slots: void processPendingDatarams(); void newConn(); void readMsg(); void displayError(QAbstractSocket::SocketError); signals: }; #endif // DIALOG_H
client.cpp
#include "dialog.h"#include "ui_dialog.h" #include <QTcpSocket>#include <QUdpSocket>#include <QTime>#include <QDebug>#include <QMessageBox>#include <QNetworkInterface>#include <QFile>#include <QFileDialog>#include <QDateTime>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <qiodevice.h> Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog){ ui->setupUi(this); setWindowTitle("client"); totalBytes = 0; recevBytes = 0; fileNameSize = 0; udpSocket = new QUdpSocket(this); uport = 8888; u2port = 7777; udpSocket->bind(QHostAddress::Broadcast, uport, QUdpSocket::ShareAddress| QUdpSocket::ReuseAddressHint); connect(udpSocket, SIGNAL(readyRead()), this, SLOT(processPendingDatarams())); tport = 6666; cClint = new QTcpSocket(this); connect(cClint,SIGNAL(readyRead()),this,SLOT(readMsg())); connect(cClint, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));}Dialog::~Dialog(){ delete ui;}// 设置地址void Dialog::setHostaddr(QHostAddress addr){ qDebug() << "--------setHostaddr---------"; hostAddr = addr; qDebug() << "hostAddr:" << hostAddr; newConn();}//设置文件名void Dialog::setFileName(QString FileName){ locFile = new QFile(FileName);}void Dialog::newConn() // 设置与服务器建立连接的。{ qDebug() << "---------newConn start---------"; blockSize = 0; cClint->abort(); cClint->connectToHost(hostAddr,tport); Time.start();}//接收文件void Dialog::readMsg(){ qDebug() << "-----------readMsg start-----------"; QDataStream in(cClint); in.setVersion(QDataStream::Qt_4_7); float useTime = Time.elapsed(); if(recevBytes <= sizeof(qint64)*2){ if((cClint->bytesAvailable() >= sizeof(qint64)*2)&& fileNameSize == 0){ //接收数据总大小信息和数据文件名大小。 in >> totalBytes >> fileNameSize; qDebug() << "totalBytes:" << totalBytes; qDebug() << "fileNameSize:" << fileNameSize; recevBytes += sizeof(qint64)*2; qDebug() << "1recevBytes:" << recevBytes; } if((cClint->bytesAvailable() >= fileNameSize) && (fileNameSize != 0)){ //开始接收文件,并建立文件。 in >> FileName; qDebug() << "FileName:" << FileName; recevBytes += fileNameSize; qDebug() << "2recevBytes:" << recevBytes; if(!locFile->open(QFile::WriteOnly)){ QMessageBox::warning(this,tr("应用程序"),tr("无法读取文件%1: \n%2").arg(FileName).arg(locFile->errorString())); return; } }else{ return; } } qDebug() << "-----------BytesArray write newFile of start-----------"; if(recevBytes < totalBytes){ recevBytes += cClint->bytesAvailable(); //把缓存区的内容写入文件。 inBlock = cClint->readAll(); locFile->write(inBlock); inBlock.resize(0); //清空缓存区 } ui->progressBar->setMaximum(totalBytes); ui->progressBar->setValue(recevBytes);//设置进度条的进度 double speed = recevBytes/useTime; ui->label->setText(tr("(%1 m/s)").arg(speed)); qDebug() << "recevBytes:" << recevBytes; qDebug() << "totalBytes:" << totalBytes; if(recevBytes == totalBytes){ locFile->close(); cClint->close(); ui->label->setText(tr("接收文件 %1完毕 ").arg(FileName)); }} void Dialog::closeEvent(QCloseEvent *){ on_cClosebtn_clicked();} void Dialog::on_cCancelBtn_clicked(){ cClint->abort(); if(locFile->isOpen()){ locFile->close(); }} void Dialog::on_cClosebtn_clicked() //关闭服务{ cClint->abort(); if(locFile->isOpen()){ locFile->close(); } close();}//处理接收到的文件名void Dialog::hansPendingFile(QString serAddress,QString fileName){ QString cIpAddress = getIP(); //"192.168.31.119"; qDebug() << "cIpAddress:" << cIpAddress; int btn = QMessageBox::information(this,tr("接收文件"), tr("文件%1是否接收?").arg(fileName), QMessageBox::Yes,QMessageBox::No); if(btn == QMessageBox::Yes){ QString name = QFileDialog::getSaveFileName(0,tr("保存文件"),fileName); if(!name.isEmpty()){ Dialog *clint = new Dialog(this); setFileName(name); setHostaddr(QHostAddress(serAddress));//默认一台电脑用。 } } else{ SendRefuse(refuse); sleep(2); on_cClosebtn_clicked(); }}QString Dialog::getIP(){ QList<QHostAddress> list = QNetworkInterface::allAddresses(); foreach (QHostAddress address, list) { if(address.protocol() == QAbstractSocket::IPv4Protocol){ if(address.toString().contains("192.168.1")||address.toString().contains("127.0")) continue; return address.toString(); } } return 0;}//处理udp发送名字信号时函数void Dialog::processPendingDatarams(){ qDebug() << "pending Datarams......." ; while(udpSocket->hasPendingDatagrams()){ QByteArray datagram; datagram.resize(udpSocket->pendingDatagramSize()); udpSocket->readDatagram(datagram.data(), datagram.size()); QDataStream in(&datagram,QIODevice::ReadOnly); QString time = QDateTime::currentDateTime() .toString("yyyy-MM-dd hh:mm:ss"); //QString clientAddress, fileName; QString fileName,serAddress; in >> serAddress >> fileName; qDebug() << "pending fileName" << fileName; hansPendingFile(serAddress,fileName); }}void Dialog::SendRefuse(MessageType refuse){ QByteArray data; QDataStream out(&data, QIODevice::WriteOnly); out << refuse; qDebug() << "data" << data; int a= udpSocket->writeDatagram(data,data.length(),QHostAddress::LocalHost, u2port); qDebug() << "------------writeDatagram a:" << a; }void Dialog::displayError(QAbstractSocket::SocketError socketError){ switch(socketError) { //RemoteHostClosedError为远处主机关闭了连接时发出的错误信号 case QAbstractSocket::RemoteHostClosedError : break; default : qDebug() << cClint->errorString(); }}
0 0
- tcp文件传输(udp发送消息确定是否接收)
- Udp消息发送接收示例
- qt 下UDP消息的接收和发送和TCP发送文件
- TCP、UDP 发送、接收0字节问题
- 使用UDP发送和接收消息
- udp发送和接收消息,服务端
- tcp udp实现文件传输(java)
- TCP与UDP的异同(服务端接收数据,客户端发送数据)
- TCP与UDP的异同(服务端接收数据,客户端发送数据)
- UDP和TCP通信机制(实现简单的数据发送与接收)
- 再论Tcp Udp 发送、接收 0字节问题
- Linux中TCP和UDP发送和接收缓冲区
- Linux中TCP和UDP发送和接收缓冲区
- VB.net基础:使用UDP发送和接收消息
- VB.net基础:使用UDP发送和接收消息
- UDP协议发送和接收消息案例详解
- Java-网络编程(IP地址)-(TCP和UDP)-(Socket)-(Udp-发送端)-(Udp-接收端)
- udp发送接收数据
- qt 错误记录
- MySQL 的 TRUNCATE 和 DELETE 区别
- 微信小程序开发教程--从零开始
- SSH整合报错:Could not obtain connection to query metadata
- 混淆矩阵
- tcp文件传输(udp发送消息确定是否接收)
- leetcode有关链表
- linux学习(10) 使用XShel连接跳板机步骤
- Quartz入门
- 快速排序的优化
- 树莓派显示中文字体
- jQuery实现的地址选择
- C#关键字partial在asp.net mvc中的应用
- linux commands