服务器
用qt designer设计出服务器界面:
上代码:
Server.pro
#------------------------------------------------- # # Project created by QtCreator 2017-02-02T09:56:26 # #------------------------------------------------- QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = Server TEMPLATE = app SOURCES += main.cpp Widget.cpp HEADERS += Widget.h FORMS += widget.ui QT += network
Widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QTcpServer> #include <QTcpSocket> #include <QTimer> #include <QFile> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); void sendData(); private slots: void on_button1_clicked(); void on_button2_clicked(); private: Ui::Widget *ui; QTcpServer *server; QTcpSocket *socket; QFile file;//文件对象 QString fileName;//文件名 qint64 fileSize;//文件大小 qint64 sendSize;//已经发送文件的大小 QTimer timer; }; #endif // WIDGET_H
Widget.cpp
#include "Widget.h" #include "ui_widget.h" #include <QFileDialog> #include <QFileInfo> #include <qDebug> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); server = new QTcpServer(this); server->listen(QHostAddress::Any,6666); ui->button1->setEnabled(false); ui->button2->setEnabled(false); connect(server,&QTcpServer::newConnection,[=](){ socket = server->nextPendingConnection(); //获取对方IP,端口 QString ip = socket->peerAddress().toString(); quint16 port = socket->peerPort(); QString str = QString("[%1:%2] 成功连接").arg(ip).arg(port); ui->textEdit->append(str); ui->button1->setEnabled(true); }); } Widget::~Widget() { delete ui; } void Widget::on_button1_clicked() { QString path = QFileDialog::getOpenFileName(this,"OPEN","../"); if(path == NULL){ ui->textEdit->append("路径读取失败");//qDebug() << "路径读取失败"; return; } //初始化发送信息 fileName.clear(); fileSize = 0; sendSize = 0; //获取信息 QFileInfo info(path); fileName = info.fileName(); fileSize = info.size(); //打开文件 file.setFileName(path); if(!file.open(QIODevice::ReadOnly)){ ui->textEdit->append("文件打开失败"); return; } ui->textEdit->append(path); ui->button1->setEnabled(false); ui->button2->setEnabled(true); connect(&timer,&QTimer::timeout,[=](){ timer.stop(); sendData(); }); } void Widget::on_button2_clicked() { QString head = QString("0&%1&%2").arg(fileName).arg(fileSize); //QString head = QString::number(fileSize); qint64 len = socket->write(head.toUtf8()); if( len < 0 ){ ui->textEdit->append("头文件没有发送成功"); file.close(); ui->button1->setEnabled(true); ui->button2->setEnabled(false); } timer.start(20);//防止粘包 } void Widget::sendData() { qint64 len = 0; do{ len = 0; char buf[4*1024] = {0};//每次发送数据大小 len = file.read(buf,sizeof(buf));//读文件 len = socket->write(buf,len);//发文件 sendSize += len; }while(len > 0); if(sendSize != fileSize){ file.close(); ui->textEdit->append("文件未发送完全"); return ; } ui->textEdit->append("文件发送完毕"); file.close(); }
main.cpp
#include "Widget.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.setWindowTitle("服务器"); w.show(); return a.exec(); }
客户端
用qt designer设计出客户端界面:
上代码:
Client.pro
#------------------------------------------------- # # Project created by QtCreator 2017-02-02T09:39:48 # #------------------------------------------------- QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = Client TEMPLATE = app SOURCES += main.cpp Widget.cpp HEADERS += Widget.h FORMS += widget.ui QT += network
Widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QTcpSocket> #include <QFile> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); private slots: void on_buttonSend_clicked(); private: Ui::Widget *ui; QTcpSocket *socket; QFile file;//文件对象 QString fileName;//文件名 qint64 fileSize;//文件大小 qint64 recvSize;//已经收到的文件的大小 bool isStart; }; #endif // WIDGET_H
Widget.cpp
#include "Widget.h" #include "ui_widget.h" #include <QHostAddress> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); socket = new QTcpSocket(this); isStart = true; connect(socket,&QTcpSocket::readyRead,[=](){ QByteArray buf = socket->readAll(); if(isStart){//接收头 isStart = false; fileName = QString(buf).section("&",0,0); fileSize = QString(buf).section("&",1,1).toInt(); recvSize = 0; file.setFileName(fileName); if(!file.open(QIODevice::WriteOnly)){ qDebug() << "打开出错"; return; } } else{//接收文件 qint64 len = file.write(buf); recvSize += len; if(recvSize == fileSize){ file.close(); qDebug() << "文件接收完成"; socket->disconnectFromHost(); socket->close(); } } }); } Widget::~Widget() { delete ui; } void Widget::on_buttonSend_clicked() { QString ip = ui->editIP->text(); quint16 port = ui->editIP_2->text().toInt(); socket->connectToHost(QHostAddress(ip),port); }
main.cpp
#include "Widget.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); }
运行出来就是这个样子:
注意:qt网络编程一定要在pro文件中添加QT += network