分为服务器和客户端
下面来具体贴出代码。 每一句的具体注释都在,帮助理解:
先贴 客户端
首先在项目文件 .pro中添加 network
widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QtcpSocket> #include<QFileDialog> #include<QFileInfo> #include<QTimer> #include<QFile> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); private slots: void on_connectBtn_clicked(); void connectedSlot(); void on_openBtn_clicked(); void on_uploadBtn_clicked(); void sendFileSlot(); private: Ui::Widget *ui; QTcpSocket *socket; QString filePath; QString fileName; int fileSize; QTimer timer; }; #endif // WIDGET_H
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
setWindowTitle("客户端");
socket = new QTcpSocket(this);
connect(socket,SIGNAL(connected()),this,SLOT(connectedSlot()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::connectedSlot()
{
ui->connectBtn->setEnabled(false);
}
void Widget::on_connectBtn_clicked()
{
socket->connectToHost("192.168.0.111",8888);
}
//打开文件按钮的槽函数 作用是得到文件,并显示文件信息
void Widget::on_openBtn_clicked()
{
//获得文件路径,并且判断是否为空
filePath = QFileDialog::getOpenFileName(this,"open","./","ALL(*.*)");
if(filePath.isEmpty())
{
return;
}
//接下来得到文件信息,使用QFileInfo
QFileInfo info(filePath);
fileName = info.fileName();
fileSize = info.size();
ui->textBrowser->append("要上传的文件为:"+fileName);
}
//发送文件 按钮的槽函数的功能是 发送文件名和文件大小。
void Widget::on_uploadBtn_clicked()
{
// 我们可以 先发送 文件名和文件大小,然后定时器停顿几秒,
//然后开始发送文件,这样的话可以有效的吧文件区分开来,
//可以 做一个timeout 信号 来开始发送文件,完美。
QString headInfo = fileName+ "##" +QString::number(fileSize);
QByteArray arr;
arr.append(headInfo);
//因为下面的参数类型是 QByteArray 所以在上面需要定义一个arr;
socket->write(arr);
timer.start(100);
//接下来连接timeout 信号和槽函数
connect(&timer,SIGNAL(timeout()),this,SLOT(sendFileSlot()));
}
// 接下来来实现 发送文件的 槽函数
//接收到 timeout信号以后 开始发送文件
void Widget::sendFileSlot()
{
timer.stop();
//开始发送文件内容
QFile file(filePath);
bool ok = file.open(QIODevice::ReadOnly);
if(true == ok)
{
QByteArray arr = file.readAll();
qint64 ret = socket->write(arr);
if( fileSize==ret)
{
ui->textBrowser->append("文件上传成功!");
file.close();
}
}
}
UI界面如下:
下面贴服务器端的 代码
1.也是先添加network
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QTcpServer>
#include<QTcpSocket>
#include<QFile>
#include <QHostAddress>
#include<QDebug>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void connectedSlot();
void recvSlot();
private:
Ui::Widget *ui;
QTcpServer *server;
QTcpSocket *socket;
QString fileName;
int fileSize;
bool flag;
};
#endif // WIDGET_H
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
setWindowTitle("接收端");
server = new QTcpServer(this);
//服务器一打开就进行监听查询,
server->listen(QHostAddress("192.168.0.111"),8888);
flag = true;
connect(server,SIGNAL(newConnection()),this,SLOT(connectedSlot()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::connectedSlot()
{
socket = server->nextPendingConnection();
if(NULL == socket)
{
return ;
}
connect(socket,SIGNAL(readyRead()),this,SLOT(recvSlot()));
}
void Widget::recvSlot()
{
QByteArray arr = socket->readAll();
if(true == flag)
{
qDebug()<<QString(arr);
QString str = QString(arr);
fileName = str.section("##",0,0);
fileSize = str.section("##",1,1).toInt();
ui->textBrowser->setText("要接收的文件信息为:"+fileName+QString::number(fileSize));
flag = false;
}
else
{
//这是后面上传文件以后需要存储的绝对路径
QFile file("F:\\"+fileName);
bool ok = file.open(QIODevice::WriteOnly);
qint64 size = 0;
if(true == ok)
{
qint64 ret = file.write(arr);
size += ret ;
if(size ==fileSize)
{
ui->textBrowser->append("文件接受完成!");
flag = true;
file.close();
}
}
}
}
ui 界面如下
文章浏览阅读1k次。AutoDWG DWG 到 PDF 转换器,比以往任何时候都更快!主要特征:批处理模式下的多文件转换;转换特定布局或图层;保留 TTF,True Type 字体,以便在 PDF 中搜索;打印、剪贴板复制和修改的权限支持;线宽可控,支持CTB文件导入;支持OLE实体;支持 PDF 自定义水印(仅限专业版)。支持命令行(仅限服务器)。支持AutoCAD 2023~R14。_crackdwg
文章浏览阅读271次。一元函数对象:函数参数1个二元函数对象:函数参数2个;一元谓词对象:函数参数1个,函数返回值是bool类型,可以作为一个判断式,谓词可以是一个仿函数,也可以是一个回调函数;二元谓词对象:函数参数2个,函数返回值是bool类型;之所以给返回布尔类型的函数对象专门命名,是因为谓词是用来为算法判断服务的。一元谓词..._二元函数对象是什么
文章浏览阅读4.2k次,点赞12次,收藏53次。tusimple数据集处理一、下载数据集1、官方下载地址 https://github.com/TuSimple/tusimple-benchmark/issues/3,数据集很大,下载速度超级慢。2、参考https://blog.csdn.net/flana/article/details/105098470百度网盘下载地址 链接: https://pan.baidu.com/s/1iyEMu0tcKaVX8nv0zBnSKw 提取码: fccj,网盘中只有zip压缩包,json文件._tusimple数据集下载
文章浏览阅读765次,点赞2次,收藏5次。算法分析程序中设计了三个函数:>函数 InitSPNode()用来建立一个稀疏矩阵的三元组表。首先输入行数、列数和非零元的值,输入(-1,-1,-1)结束输入。>函数showMatrix()用来输出稀疏矩阵算法中按矩阵a的列进行循环处理,对a的每一列扫描三元组,找出相应的元素,若找到,则交换其行号与列号,并存储到矩阵b的三元组中。>函数TransposeSMatrix()用来完成稀疏矩阵的转置算法。算法主要的工作是在p和col的两重循环中完成,时间复杂度为O(n_代码如下: /*name:雷桂艺 time:2021年12月8日17:32 version:1.0 description:步骤
文章浏览阅读4.6w次,点赞4次,收藏2次。最近在学习maven,实时发现问题,实时记录下来,以备后用同事的正常项目,我正常倒入Eclipse中以后,pom.xml文件报错,打开该文件,前2行有下划红线 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">给出的提示信息_could not transfer artifact pom.xml
文章浏览阅读5k次。一、ASCII码ASCII码实际上就是键盘上输入的字符,在计算机中二进制形式ASCII码表如下图所示:这张表中包括数字、字母、符号,共128个字符,所以可以用7位二进制编码,为了存入计算机,通常在最高位补0,凑足1B。可印刷字符:32~126,其余为控制、通信字符。数字:48(0011 0000)~57(0011 1001)大写字母:65(0100 0001)~90(0101 1010)小..._ascii码 csdn
文章浏览阅读5.6w次,点赞16次,收藏34次。《python机器学习及实践》第二章第一个代码运行报错: AttributeError: 'numpy.ndarray' object has no attribute 'value_counts' # coding: utf-8# In[1]:# 导入pandas与numpy工具包。import pandas as pdimport numpy as np# 创建特征列表_attributeerror: 'numpy.ndarray' object has no attribute 'value_counts
文章浏览阅读5.8k次,点赞2次,收藏3次。原因:用jsonp跨域访问, 会注册callback, 生产一个随机的callback,正确的jsonp格式应该是 callback({"id" : "1","name" : "小王"}); 所以我们需要定义callback,前台指定回调函数jsonpCallback:"successCallback",后台指定返回的json格式:String result = "s_jsonp callback 有返回值,但是进入error
文章浏览阅读17次。本系统带文档lw万字以上文末可领取本课题的JAVA源码参考。
文章浏览阅读607次。前言策略模式是指定义了算法家族并分别分装起来,让他们之间可以互相替换,使得算法的变化不会影响使用算法的用户策略模式最常用的场景是一个系统需要动态地在集中算法中选择,例如支付场景,接下来我们就以支付场景为里来解释策略模式案例定义支付抽象类Payment首先我们定义支付抽象类Payment :public abstract class Payment { public abstract String getName(); protected abstract double quer_策略模式使用
文章浏览阅读199次。现代社会,我们已经离不开手机。上班途中、吃饭排队、睡觉前,只要有一点剩余时间,就会沉迷于手机之中。一天之中,我们会看很多的爽文、很多的短视频,但再回顾时,又发现什么都没有记住或学到。开始后悔这一天白过,发誓第二天少玩手机,禁用手机。然后,第二天重复前一天的懊悔。玩手机本没有问题,我们其实在玩得过程中,把阅读到的有趣内容进行吸收与整合,变成自己的东西。我们一天会很看很多资讯,新闻、干货。只有在用到的时候,我们发现好像在某某博客、某某平台看到过这篇文章提供..._用更多的财物知识将自己打造成
文章浏览阅读7.9k次。本来想一篇文章把流程开发介绍完的,后来发现实在是太多了,只好分成两部分了。上一篇很简单的介绍了下k2流程的设计和配置,希望大家的流程都已经发布成功了。这部分接着上面讲,主要说一下k2流程api的使用。我们要在k2web中新建一下几个页面:LeaveProcess\Startflow.aspx:请假流程发起界面LeaveProcess\Audit.aspx:请假流程审批界面index.a_k2 blackpearl