Qt socket制作一个简单的文件传输系统

服务器

用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

原文地址:https://www.cnblogs.com/StringSir/p/8445797.html

时间: 2024-11-08 21:53:01

Qt socket制作一个简单的文件传输系统的相关文章

制作一个简单的用户界面

制作一个简单的用户界面 这节课里面,我们来开发一个XML布局文件,这个布局文件里面会包含一个text field,文本输入框,和一个按钮button.下一节课里面,会教大家怎么在按下一个按钮的时候,跳转到另一个Activity. 这里先简单解释一下Android界面的构成.AndroidApp的界面是使用View和ViewGroup构建起来的.View通常就是我们常见的UI小部件,比如按钮Button.文本控件TextView等:而ViewGroup是一个View的容器,它可以限制这个容器里面的

【FLEX&amp;YACC】第二天制作一个简单计算器

首先写词法分析器: 词法分析器要返回记号: "+" 返回ADD "-" 返回SUB "*" 返回MUL "/" 返回DIV 输入的实数全部被当作double类型处理 换行符返回CR calc.l: %{#include <stdio.h>#include "y.tab.h"int yywrap(void){ /*免链接库文件*/    return 1;}%}%%[ \t]    { ;}&qu

实例学习SSIS(一)--制作一个简单的ETL包

原文:实例学习SSIS(一)--制作一个简单的ETL包 导读: 实例学习SSIS(一)--制作一个简单的ETL包 实例学习SSIS(二)--使用迭代 实例学习SSIS(三)--使用包配置 实例学习SSIS(四)--使用日志记录和错误流重定向 实例学习SSIS(五)--理论介绍SSIS 参考内容:SQLServer2005的帮助文档. ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.zh-CHS/sqltut9/html/d6d5bb1f-4cb1-4605-9cd6-f60

利用java的Socket实现一个简单hello/hi聊天程序

利用java的Socket实现一个简单hello/hi聊天程序 首先,我们来用java实现一个简单的hello/hi聊天程序.在这个程序里,我学习到了怎么用socket套接套接字来进行编程.简单理解了一些关于socket套接字和底层调用的关系.关于java的封装思想,我学会了一些东西,java里真的是万物皆对象.还学到了一点多线程的知识. TCP 在这里,不得不先介绍以下TCP.TCP是传输层面向连接的协议.提供了端到端的进程之间的通信方式.TCP在通信之前要先建立连接.这里我们称这个建立连接的

iOS 制作一个简单的画板

制作简单画板 作为iOS初学者,在学习完UI的几个简单控件(UILable,UITextField,UIButton)之后,就可以制作一个简单的画图板demo,以下是具体制作流程(在MRC下),如有不足之处,还请各位大神们指教 0.0. 1.搭建界面,主要由UIButton,UITextField组成,底部的按钮是UITextField的一个自定义键盘(inputView) . - (void)viewDidLoad { [super viewDidLoad]; //创建菜单按钮 UIButto

jfinal初接触,一个简单的文件上传例子

写了个上传的小例子. 从jfinal官网下载jfinal-1.8_demo_for_jsp.zip 然后下载jfinal-1.8-lib.zip 按要求删掉该删除的,引入一些包,之后的项目结构: DemoConfig.java中配置路由,只留下了根路径: /** * 配置路由 */ public void configRoute(Routes me) { me.add("/", CommonController.class); //me.add("/blog", B

制作一个简单的文本框输入的网页

题目:制作一个简单的网页(包含一个文本框.一个按钮),在页面上输出用户在文本框输入的内容,要求用JavaScript获取文本框内容. 一.首先利用html在网页上制作表单,代码如下: **onclick事件:onclick 事件会在对象被点击时发生. 二.利用js获取输入信息,并将其输出: 相关知识: 1.给用户确认消息,真正实现交互,使用语句confirm();给用户提示信息,实现单向通信,使用语句alert(). 三.运行结果: 1.用浏览器打开结果如下: 2.输入文本框内容,点击[提交]:

c# 自己制作一个简单的项目倒计时器

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace date { public partial class Form1 : Form { public Form1() { InitializeCompo

如何使用AEditor制作一个简单的H5交互页demo

转载自:http://www.alloyteam.com/2015/06/h5-jiao-hu-ye-bian-ji-qi-aeditor-jie-shao/ 本教程演示如何使用AEditor制作一个简单的H5交互页demo: 交互页demo地址: 点击打开H5交互页demo AEditor访问地址: http://aeditor.alloyteam.com Step1:设置页面背景颜色 首先我们设置页面的背景颜色,右击舞台点击“设置背景”: 然后在背景颜色中填上色值rgb(38, 61, 10