赞
踩
目录
利用Tcp协议实现服务器端和客户端数据的传输,客户端向服务器端传输文件(音频、视频、文本)类似客户端上传文件
头文件:
#include <QWidget>
#include <QTcpSocket>
#include <QFileDialog>//显示文件对话框
#include <QFileInfo>//获取文件信息
#include <QTimer>
客户端只需一个接收套接字 tcpSocket = new QTcpSocket(this);
tcpSocket->connectToHost(Ip,port);连接到服务器端
开辟一个QByteArray array内存空间,通过信号与槽connect
QString filePath = QFileDialong::getOpenFileName(this);
QFileInfo FileData(filePath);//获取文件信息
filename = FileData.fileName();//获得文件名字
filesize = FileData.size();//获得文件大小 字节
QFile file创建一个文件描述符,
文件的发送分为两个部分:
a.先发送一个包含文件信息的字符串类型为" filename**filesize "
QString head = filename + "**" + QString::number(filename); qint64 length = tcpSocket->write(head.toutf8); if(length>0)//发送成功 myTimer->start(20);//设置一个定时器 防止内容粘包 else //发送不成功 file.close();
b.防止粘包发送成功后设置一个延迟 设置一个定时器myTimer 开始发送文件本身
myTimer = new QTimer(this); connect(myTimer,&QTimer::timeout, this ,[&](){ myTimer->stop(); qint64 len; qint64 sendSize = 0;//已经发送文件大小 do{ char buf[4*1024] = {0};//一次读取char这么大 len = 0; len = file.read(buf,sizeof(buf));//从file中读取4096放到buf中 tcpSocket->write(buf,len);//写入 sendSize += len; ui->progressBar->setValue(sendSize/1024);//设置进度条 }while(len>0); if(sendSize == filesize)//发送内存大小和实际文件内存大小相等传输完毕 { file.close(); tcpSocket->disconnectFromHost();//断开连接 tcpSocket->close(); } });
头文件:
#include <QTcpServer>
监听套接字
#include <QTcpSocket>
通信套接字
QTcpServer *tcpserver;
监听套接字对象
QTcpSocket *clientConnection = nullptr;
通信套接字对象
1. 监听对象开辟空间
tcpserver = new QTcpServer(this);
调用listen()监听 这里使用的是本地主机127.0.0.1的Ip地址
tcpserver ->listen(QHostAddress::LocalHost,ui->lineEdit->text().toInt());
2.连接客户端 接受文件
connect(tcpserver,&QTcpServer::newConnection,this,[&](){
clientConnection = tcpserver->nextPendingConnection();
clientConnection->write("Welcome to connect to the server!");//连接成功向客户端发送成功连接字样//接收端
connect(clientConnection, QTcpSocket::readyRead,this,[&](){
QByteArray array = clientConnection->readAll();
if(headInfo){ //第一次读出的信息应该是head文件信息
headInfo = false;
recvSize = 0;
filename = QString(array).section("**",0,0); //分割出需要的信息
filesize = QString(array).section("**",1,1).toInt();file.setFileName(filename);
file.open(QIODevice::WriteOnly);//发送端只读打开//设置进度条
ui->progressBar->setMinimum(0);
ui->progressBar->setMaximum(filesize/1024);
ui->progressBar->setValue(0);//初始为0
}
else{//这里收到的文件是文件本身
qint64 length = file.write(array);
if(length >0)
recvSize += length;
ui->progressBar->setValue(recvSize/1024);
if(recvSize == filesize)
{
//文件接受完毕
QMessageBox::information(this,"完成","文件接受完成");
file.close();
}
}
});
} );
- #ifndef WIDGET_H
- #define WIDGET_H
-
- #include <QWidget>
- #include <QTcpServer>
- #include <QTcpSocket>
- #include <QFileDialog>
- #include <QFile>
- #include <QMessageBox>
-
-
- namespace Ui {
- class Widget;
- }
-
- class Widget : public QWidget
- {
- Q_OBJECT
-
- public:
- explicit Widget(QWidget *parent = 0);
- ~Widget();
-
- private slots:
- void on_pushButton_clicked();
-
- private:
- Ui::Widget *ui;
- QTcpServer *tcpserver;//监听服务器端套接字
- QTcpSocket *clientConnection = nullptr;//通信套接字
-
- bool headInfo = true;
- QString filename;
- qint64 filesize;
- qint64 recvSize;//收到文件的大小
- QFile file;
- };
-
- #endif // WIDGET_H
- #include "widget.h"
- #include "ui_widget.h"
- #include <QDebug>
-
- Widget::Widget(QWidget *parent) :
- QWidget(parent),
- ui(new Ui::Widget)
- {
- ui->setupUi(this);
- setWindowTitle("服务器");
- ui->lineEdit->setText("8080");//初始端口号值
-
- tcpserver = new QTcpServer(this);
-
- }
-
- Widget::~Widget()
- {
- delete ui;
- }
-
- void Widget::on_pushButton_clicked()
- {
-
-
- tcpserver ->listen(QHostAddress::LocalHost,ui->lineEdit->text().toInt());//(LocalHost本机环回地址)
-
- connect(tcpserver,&QTcpServer::newConnection,this,[&](){
- clientConnection = tcpserver->nextPendingConnection();
- clientConnection->write("Welcome to connect to the server!");
-
- //接收端
- connect(clientConnection, QTcpSocket::readyRead,this,[&](){
- QByteArray array = clientConnection->readAll();
- if(headInfo){ //第一次读出的信息应该是head文件信息
- headInfo = false;
-
-
- recvSize = 0;
- filename = QString(array).section("**",0,0); //分割出需要的信息
- filesize = QString(array).section("**",1,1).toInt();
-
- file.setFileName(filename);
- file.open(QIODevice::WriteOnly);//发送端只读打开
-
- //设置进度条
- ui->progressBar->setMinimum(0);
- ui->progressBar->setMaximum(filesize/1024);
- ui->progressBar->setValue(0);//初始为0
- }
- else{//这里收到的文件是文件本身
- qint64 length = file.write(array);
- if(length >0)
- recvSize += length;
- ui->progressBar->setValue(recvSize/1024);
- if(recvSize == filesize)
- {
- //文件接受完毕
- QMessageBox::information(this,"完成","文件接受完成");
- file.close();
- }
-
- }
- });
- } );
- ui->pushButton->setEnabled(false);
- }
- #ifndef WIDGET_H
- #define WIDGET_H
-
- #include <QWidget>
- #include <QTcpServer>
- #include <QTcpSocket>
- #include <QFileDialog>//显示文件对话框
- #include <QFileInfo>//获取文件信息
- #include <QTimer>
-
- namespace Ui {
- class Widget;
- }
-
- class Widget : public QWidget
- {
- Q_OBJECT
-
- public:
- explicit Widget(QWidget *parent = 0);
- ~Widget();
-
- private slots:
- void on_pushButton_clicked();
-
- void on_pushButton_2_clicked();
-
- void on_pushButton_3_clicked();
-
- private:
- Ui::Widget *ui;
- QTcpSocket *tcpSocket; //客户端只需要一个接受套接字
- QString filename;
- qint64 filesize;
- QFile file; //文件描述符
- QTimer *myTimer; //定时器
- };
-
- #endif // WIDGET_H
- #include "widget.h"
- #include "ui_widget.h"
- #include <QDebug>
-
- Widget::Widget(QWidget *parent) :
- QWidget(parent),
- ui(new Ui::Widget)
- {
- ui->setupUi(this);
- setWindowTitle("客户端");
-
- tcpSocket = new QTcpSocket(this);
-
- connect(tcpSocket, &QTcpSocket::readyRead,this,[&](){
- QByteArray array = tcpSocket->readAll();
- qDebug()<<"服务器: "<<array;
- });
-
- myTimer = new QTimer(this);
- connect(myTimer,&QTimer::timeout, this ,[&](){
- myTimer->stop();
-
- qint64 len;
- qint64 sendSize = 0;//已经发送文件大小
-
- do{
- char buf[4*1024] = {0};//一次读取char这么大
- len = 0;
- len = file.read(buf,sizeof(buf));
- tcpSocket->write(buf,len);
- sendSize += len;
- ui->progressBar->setValue(sendSize/1024);
- }while(len>0);
- if(sendSize == filesize )
- {
- file.close();
- tcpSocket->disconnectFromHost();//断开连接
- tcpSocket->close();
- }
- });
-
- }
-
- Widget::~Widget()
- {
- delete ui;
- }
-
- void Widget::on_pushButton_clicked()//连接按钮
- {
- //连接服务器
- tcpSocket->connectToHost(ui->lineEdit->text(),ui->lineEdit_2->text().toInt());
- }
-
- void Widget::on_pushButton_2_clicked()//打开按钮
- {
- QString filePath = QFileDialog::getOpenFileName(this);
-
- //发送文件时先发送一个文件名字和文件大小,如果两端文件大小相同说明发送完毕
- QFileInfo FileData(filePath);//获取文件信息
- filename = FileData.fileName();//获得文件名字
- filesize = FileData.size();//获得文件大小
-
- qDebug()<<"文件名:"<<filename;
- qDebug()<<"文件大小:"<<filesize;
-
- if(!filePath.isEmpty())
- {
- ui->label_3->setText(filePath);//显示文件名字
- file.setFileName(filePath);
- file.open(QIODevice::ReadOnly);//发送端只读打开
- }
-
- //设置进度条
- ui->progressBar->setMinimum(0);
- ui->progressBar->setMaximum(filesize/1024);
- ui->progressBar->setValue(0);//初始为0
- }
-
- void Widget::on_pushButton_3_clicked()
- {
- //头信息
- QString head = filename + "**" + QString::number(filesize); //强制类型转换成字符串
- //发送head文件
- qint64 length = tcpSocket->write(head.toUtf8());
- if(length>0)//发送成功
- myTimer->start(20);//设置一个定时器 防止内容粘包
-
- else //发送不成功
- file.close();
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。