This commit is contained in:
sonichy 2022-02-11 13:25:11 +08:00
commit 6649fd406e
12 changed files with 503 additions and 0 deletions

BIN
FileTrans Normal file

Binary file not shown.

BIN
FileTrans.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

22
FileTrans.pro Normal file
View File

@ -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

9
README.md Normal file
View File

@ -0,0 +1,9 @@
# File Trans
基于 Qt Socket 的文件传输软件。
## 界面
![alt](preview.jpg)
## 参考
[Qt文服务器](https://github.com/sonichy/HTYServer)
[Android手机间使用socket进行文件互传实例](https://www.cnblogs.com/zhujiabin/p/7139644.html)

40
icon.htm Normal file
View File

@ -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>

4
install.sh Normal file
View File

@ -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

13
main.cpp Normal file
View File

@ -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();
}

193
mainwindow.cpp Normal file
View File

@ -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();
}
});
}

40
mainwindow.h Normal file
View File

@ -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

177
mainwindow.ui Normal file
View File

@ -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>

BIN
preview.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

5
res.qrc Normal file
View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>FileTrans.png</file>
</qresource>
</RCC>