first
This commit is contained in:
commit
6649fd406e
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
|
@ -0,0 +1,22 @@
|
|||
QT += core gui network
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = FileTrans
|
||||
TEMPLATE = app
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
mainwindow.cpp
|
||||
|
||||
HEADERS += \
|
||||
mainwindow.h
|
||||
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui
|
||||
|
||||
RESOURCES += \
|
||||
res.qrc
|
|
@ -0,0 +1,9 @@
|
|||
# File Trans
|
||||
基于 Qt Socket 的文件传输软件。
|
||||
|
||||
## 界面
|
||||

|
||||
|
||||
## 参考
|
||||
[Qt文服务器](https://github.com/sonichy/HTYServer)
|
||||
[Android手机间使用socket进行文件互传实例](https://www.cnblogs.com/zhujiabin/p/7139644.html)
|
|
@ -0,0 +1,40 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>LOGO</title>
|
||||
<style>
|
||||
canvas { border:1px solid gray; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas" width="512" height="512"></canvas>
|
||||
<script>
|
||||
var canvas = document.getElementById("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.lineTo(70, 30);
|
||||
ctx.lineTo(350, 30);
|
||||
ctx.lineTo(440, 130);
|
||||
ctx.lineTo(440, 480);
|
||||
ctx.lineTo(70, 480);
|
||||
ctx.closePath();
|
||||
ctx.fillStyle = '#05a8ec';
|
||||
ctx.fill();
|
||||
ctx.lineWidth = 5;
|
||||
ctx.stroke();
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.lineTo(350, 30);
|
||||
ctx.lineTo(350, 130);
|
||||
ctx.lineTo(440, 130);
|
||||
ctx.stroke();
|
||||
|
||||
ctx.fillStyle = "black";
|
||||
ctx.font = "500px 方正粗圆简体";
|
||||
var text = "⇅";
|
||||
var x = (canvas.width - ctx.measureText(text).width)/2;
|
||||
ctx.fillText(text, x, 400);
|
||||
</script>
|
||||
<body>
|
||||
</html>
|
|
@ -0,0 +1,4 @@
|
|||
filename=FileTrans
|
||||
s="[Desktop Entry]\nName=文件传输\nComment=A file transfer base on Qt.\nExec=`pwd`/$filename\nIcon=`pwd`/$filename.png\nPath=`pwd`\nTerminal=false\nType=Application\nCategories=Net;"
|
||||
echo -e $s > $filename.desktop
|
||||
cp `pwd`/$filename.desktop ~/.local/share/applications/$filename.desktop
|
|
@ -0,0 +1,13 @@
|
|||
#include "mainwindow.h"
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
qSetMessagePattern("[ %{file}: %{line} ] %{message}");
|
||||
QApplication a(argc, argv);
|
||||
a.setOrganizationName("HTY");
|
||||
a.setApplicationName("FileTrans");
|
||||
MainWindow w;
|
||||
w.show();
|
||||
return a.exec();
|
||||
}
|
|
@ -0,0 +1,193 @@
|
|||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include <QDebug>
|
||||
#include <QNetworkInterface>
|
||||
#include <QFileDialog>
|
||||
#include <QIntValidator>
|
||||
#include <QMessageBox>
|
||||
#include <QMimeDatabase>
|
||||
#include <QDateTime>
|
||||
#include <QMetaEnum>
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow),
|
||||
settings(QApplication::organizationName(), QApplication::applicationName())
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setFixedSize(400, 500);
|
||||
ui->lineEdit_port->setValidator(new QIntValidator(1024, 65535, this));
|
||||
ui->lineEdit_root_dir->setText(settings.value("Directory", QApplication::applicationDirPath()).toString());
|
||||
QAction *action_browser = new QAction;
|
||||
action_browser->setIcon(QIcon::fromTheme("folder"));
|
||||
ui->lineEdit_root_dir->addAction(action_browser, QLineEdit::TrailingPosition);
|
||||
connect(action_browser, &QAction::triggered, [=](){
|
||||
QString dir = QFileDialog::getExistingDirectory(this, tr("Root Directory"),
|
||||
settings.value("Directory", QApplication::applicationDirPath()).toString(),
|
||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||
if (dir != "") {
|
||||
ui->lineEdit_root_dir->setText(dir);
|
||||
settings.setValue("Directory", ui->lineEdit_root_dir->text());
|
||||
}
|
||||
});
|
||||
|
||||
QList<QNetworkInterface> list = QNetworkInterface::allInterfaces();
|
||||
foreach (QNetworkInterface interface, list) {
|
||||
QList<QNetworkAddressEntry> entryList = interface.addressEntries();
|
||||
foreach (QNetworkAddressEntry entry, entryList) {
|
||||
if (!entry.ip().toString().contains("::") && entry.ip().toString() != "127.0.0.1") {
|
||||
IP = entry.ip().toString();
|
||||
ui->lineEdit_ip->setText(IP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
connect(ui->pushButton_start, &QPushButton::toggled, [=](bool b){
|
||||
if (b) {
|
||||
state = 0;
|
||||
qint64 port = 9999;
|
||||
while (!tcpServer->listen(QHostAddress::Any, port)) {
|
||||
port--;
|
||||
}
|
||||
ui->label_local->setText(IP + ":" + QString::number(port));
|
||||
ui->lineEdit_port->setText(QString::number(port));
|
||||
ui->textBrowser->clear();
|
||||
ui->textBrowser->append("[" + QDateTime::currentDateTime().toString("HH:mm:ss") + "] 监听:" + IP + ":" + QString::number(port));
|
||||
ui->pushButton_start->setText("Stop");
|
||||
} else {
|
||||
tcpServer->close();
|
||||
ui->pushButton_start->setText("Start");
|
||||
}
|
||||
});
|
||||
|
||||
connect(ui->pushButton_add, &QPushButton::clicked, [=]{
|
||||
if (path == "")
|
||||
path = ".";
|
||||
QStringList SL_path = QFileDialog::getOpenFileNames(this, "上传文件", path);
|
||||
//qDebug() << SL_path;
|
||||
for (int i=0; i<SL_path.length(); i++) {
|
||||
QString filepath = SL_path.at(i);
|
||||
path = filepath;
|
||||
//qDebug() << filepath;
|
||||
upload(filepath);
|
||||
}
|
||||
});
|
||||
|
||||
connect(ui->pushButton_clear, &QPushButton::clicked, [=]{
|
||||
ui->textBrowser->clear();
|
||||
});
|
||||
|
||||
tcpServer = new QTcpServer(this);
|
||||
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newConnect()));
|
||||
ui->pushButton_start->toggle();
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void MainWindow::newConnect()
|
||||
{
|
||||
tcpSocket = tcpServer->nextPendingConnection();
|
||||
ui->textBrowser->append("[" + QDateTime::currentDateTime().toString("HH:mm:ss") + "] " + tcpSocket->peerAddress().toString().replace("::ffff:","") + ":" + QString::number(tcpSocket->peerPort()));
|
||||
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readyRead()));
|
||||
|
||||
connect(tcpSocket, &QTcpSocket::disconnected, [=](){
|
||||
qDebug() << state;
|
||||
if (state == 0) {
|
||||
state = 1;
|
||||
} else {
|
||||
file.close();
|
||||
state = 0;
|
||||
length = 0;
|
||||
}
|
||||
});
|
||||
|
||||
connect(tcpSocket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error), [=](QAbstractSocket::SocketError socketError){
|
||||
qDebug() << socketError;
|
||||
QMetaEnum metaEnum = QMetaEnum::fromType<QAbstractSocket::SocketError>();
|
||||
QString errorString = metaEnum.valueToKey(socketError);
|
||||
ui->textBrowser->append("[" + QDateTime::currentDateTime().toString("HH:mm:ss") + "] " + errorString);
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::readyRead()
|
||||
{
|
||||
QByteArray BA = tcpSocket->readAll();
|
||||
//qDebug() << BA ;
|
||||
if (state == 0) {
|
||||
QString filename = BA;
|
||||
ui->textBrowser->append("[" + QDateTime::currentDateTime().toString("HH:mm:ss") + "] " + "接收:" + filename);
|
||||
QString filepath = ui->lineEdit_root_dir->text() + "/" + filename;
|
||||
file.setFileName(filepath);
|
||||
file.open(QIODevice::WriteOnly);
|
||||
} else {
|
||||
file.write(BA);
|
||||
length += BA.length();
|
||||
ui->statusBar->showMessage("接收:" + BS(length));
|
||||
}
|
||||
}
|
||||
|
||||
QString MainWindow::BS(long b)
|
||||
{
|
||||
QString s = "";
|
||||
if (b > 999999999) {
|
||||
s = QString::number(b/(1024*1024*1024.0), 'f', 2) + " GB";
|
||||
} else {
|
||||
if (b > 999999) {
|
||||
s = QString::number(b/(1024*1024.0), 'f', 2) + " MB";
|
||||
} else {
|
||||
if (b > 999) {
|
||||
s = QString::number(b/(1024.0), 'f', 2) + " KB";
|
||||
} else {
|
||||
s = QString::number(b) + " B";
|
||||
}
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void MainWindow::upload(QString filepath)
|
||||
{
|
||||
qint64 port = ui->lineEdit_port->text().toInt();
|
||||
QTcpSocket *tcpSocket1 = new QTcpSocket(this);
|
||||
connect(tcpSocket1, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error), [=](QAbstractSocket::SocketError socketError){
|
||||
qDebug() << socketError;
|
||||
QMetaEnum metaEnum = QMetaEnum::fromType<QAbstractSocket::SocketError>();
|
||||
QString errorString = metaEnum.valueToKey(socketError);
|
||||
ui->textBrowser->append("[" + QDateTime::currentDateTime().toString("HH:mm:ss") + "] " + errorString);
|
||||
});
|
||||
|
||||
tcpSocket1->connectToHost(QHostAddress(ui->lineEdit_ip->text()), port);
|
||||
connect(tcpSocket1, &QTcpSocket::connected, [=](){
|
||||
QString filename = QFileInfo(filepath).fileName();
|
||||
tcpSocket1->write(filename.toUtf8());
|
||||
tcpSocket1->close();
|
||||
ui->textBrowser->append("[" + QDateTime::currentDateTime().toString("HH:mm:ss") + "] 上传:" + filename);
|
||||
});
|
||||
|
||||
QTcpSocket *tcpSocket2 = new QTcpSocket(this);
|
||||
connect(tcpSocket2, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error), [=](QAbstractSocket::SocketError socketError){
|
||||
qDebug() << socketError;
|
||||
QMetaEnum metaEnum = QMetaEnum::fromType<QAbstractSocket::SocketError>();
|
||||
QString errorString = metaEnum.valueToKey(socketError);
|
||||
ui->textBrowser->append("[" + QDateTime::currentDateTime().toString("HH:mm:ss") + "] " + errorString);
|
||||
});
|
||||
tcpSocket2->connectToHost(QHostAddress(ui->lineEdit_ip->text()), port);
|
||||
connect(tcpSocket2, &QTcpSocket::connected, [=](){
|
||||
qint64 length1 = 0;
|
||||
QFile file(filepath);
|
||||
if (file.open(QIODevice::ReadOnly)) {
|
||||
while (!file.atEnd()) {
|
||||
QByteArray BA = file.read(10240); //每次读取10k数据
|
||||
tcpSocket2->write(BA);
|
||||
//qDebug() << "\b" << file.pos();
|
||||
length1 += 10240;
|
||||
ui->statusBar->showMessage("上传:" + BS(length1) + "/" + BS(file.size()));
|
||||
}
|
||||
ui->textBrowser->append("[" + QDateTime::currentDateTime().toString("HH:mm:ss") + "] " + "上传完成");
|
||||
tcpSocket2->close();
|
||||
}
|
||||
});
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QSettings>
|
||||
#include <QTcpServer>
|
||||
#include <QTcpSocket>
|
||||
#include <QFile>
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
QSettings settings;
|
||||
QString IP, path;
|
||||
QTcpServer *tcpServer;
|
||||
QTcpSocket *tcpSocket;
|
||||
int state;
|
||||
QFile file;
|
||||
qint64 length;
|
||||
QString BS(long b);
|
||||
void upload(QString filepath);
|
||||
|
||||
private slots:
|
||||
void newConnect();
|
||||
void readyRead();
|
||||
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
|
@ -0,0 +1,177 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>500</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>文件传输</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="res.qrc">
|
||||
<normaloff>:/FileTrans.png</normaloff>:/FileTrans.png</iconset>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>IP</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Port</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>根目录</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>本机</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QLabel" name="label_local">
|
||||
<property name="text">
|
||||
<string>ip:port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="lineEdit_port">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="lineEdit_root_dir"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_ip"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_start">
|
||||
<property name="text">
|
||||
<string>Start</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_add">
|
||||
<property name="text">
|
||||
<string>+</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_clear">
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="textBrowser"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>27</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar"/>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<tabstops>
|
||||
<tabstop>lineEdit_ip</tabstop>
|
||||
<tabstop>lineEdit_port</tabstop>
|
||||
<tabstop>lineEdit_root_dir</tabstop>
|
||||
<tabstop>pushButton_start</tabstop>
|
||||
<tabstop>pushButton_add</tabstop>
|
||||
<tabstop>pushButton_clear</tabstop>
|
||||
<tabstop>textBrowser</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="res.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
Binary file not shown.
After Width: | Height: | Size: 116 KiB |
Loading…
Reference in New Issue