广告位联系
返回顶部
分享到

基于Python搭建局域网大文件分享传输工具

python 来源:互联网 作者:佚名 发布时间:2025-01-01 17:07:25 人浏览
摘要

1.简介 由于单位不让用优盘、禁止用飞秋、也不准使共享,禁用FTP,也禁止搭建网站,且目前局域网内用的IM不支持1G以上文件传输,于是在找适合内网的大文件传输方法。开始搭建网盘,但上

1.简介

由于单位不让用优盘、禁止用飞秋、也不准使共享,禁用FTP,也禁止搭建网站,且目前局域网内用的IM不支持1G以上文件传输,于是在找适合内网的大文件传输方法。开始搭建网盘,但上传一次、下载一次,效率还是有点低。后来用Everything的HTTP服务器,结果把整个硬盘都分享了,太不安全。于是就自己做了这个简单的文件分享工具。资源已打包可自行下载。

HTTP分享,利用Flask搭建了一个Web服务器,选择要分享的文件启动后,将生成的链接发给对方,对方就可以通过浏览器下载。
FTP分享用pyftpdlib搭建了一个FTP服务器,同样生成链接后,对方可以通过一些浏览器或FTP客户端下载,也可以通过程序提供的工具下载文件。

2.运行效果

3.相关源码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

from PyQt5.QtWidgets import QApplication, QRadioButton, QMainWindow, QLabel, QComboBox, QLineEdit, QPushButton, QMessageBox, QToolButton, QFileDialog, QDialog

from PyQt5.QtCore import QDir, Qt, QThread, pyqtSignal

from PyQt5 import QtGui, QtCore, QtWidgets

from PyQt5.QtGui import QIcon,QFont

import sys

import os

import random

import netifaces

from flask import Flask, send_file

from concurrent.futures import ThreadPoolExecutor

from pyftpdlib.authorizers import DummyAuthorizer

from pyftpdlib.handlers import FTPHandler

from pyftpdlib.servers import ThreadedFTPServer

from ftplib import FTP

from urllib.parse import urlparse

 

class HelpWindow(QDialog):

    def __init__(self):

        super().__init__()

        self.setWindowTitle("帮助")

        self.setFixedSize(300, 280)

        self.center()

        self.setWindowFlags(Qt.WindowCloseButtonHint | Qt.WindowTitleHint)

        self.label = QLabel(self)

        self.label.setText("1、选择文件传输协议;2、输入端口号(建议10000~60000,一般默认即可); \

                            3、选择文件所在目录;4、选择要分享的文件;5、点击启动按钮,\

                           若防火墙弹出警示点击允许访问即可;6、将生成的链接复制发送给接收方, \

                           接收方通过浏览器访问即可下载。若通过FTP协议分享还可通过FTP客户端软件  \

                            或本程序的“接收FTP文件”按钮下载。注意:传输完成后请及时关闭程序, \

                            以免造成数据泄露和网络安全隐患。")

        self.label.setGeometry(10, 10, 280, 260)

        self.label.setWordWrap(True)

        font = QFont()

        font.setPointSize(10)  

        font.setBold(True)  

        self.label.setFont(font)

         

    def center(self):

        screen = QApplication.desktop().screenGeometry()

        window = self.geometry()

        x = (screen.width() - window.width()) // 2

        y = (screen.height() - window.height()) // 2

        self.move(x, y)

 

class DownloadThread(QThread):

    finished = pyqtSignal(bool)

    ftp = FTP()

 

    def __init__(self, ftp_url):

        super().__init__()

        self.ftp_url = ftp_url

 

    def run(self):

        parsed_url = urlparse(self.ftp_url)

        username = parsed_url.username

        password = parsed_url.password

        host = parsed_url.hostname

        port = parsed_url.port

        filename = parsed_url.path.rsplit('/', 1)[-1]

        if len(filename)==0:

            downloadfile = False

        else:

            downloadfile = True

        try:

            self.ftp.connect(host, port)

            self.ftp.encoding = 'utf-8'

            self.ftp.login(user=username, passwd=password)

 

            current_dir = os.getcwd()

            current_dir = current_dir.replace("\\", "/")

            random_int = random.randint(100, 999)

            mulu = "接收文件_" + str(random_int)

            LocalDir = current_dir + "/" + mulu

            if not os.path.exists(LocalDir):

                os.makedirs(LocalDir)

            if downloadfile:#下载一个文件

                Local = os.path.join(LocalDir, filename)

                self.DownLoadFile(Local,filename)

            else:#下载整个目录

                self.DownLoadFileTree(LocalDir,"/")

            self.ftp.quit()

            self.finished.emit(True)

        except Exception as e:

            self.finished.emit(False)

 

    def DownLoadFile(self, LocalFile, RemoteFile):  # 下载单个文件

        with open(LocalFile, 'wb') as file_handler:

            self.ftp.retrbinary('RETR ' + RemoteFile, file_handler.write)

        file_handler.close()

        return True

 

    def DownLoadFileTree(self, LocalDir, RemoteDir):  # 下载整个目录下的文件

        print("远程文件夹remoteDir:", RemoteDir)

        if not os.path.exists(LocalDir):

            os.makedirs(LocalDir)

        self.ftp.cwd(RemoteDir)

        RemoteNames = self.ftp.nlst()

        print("远程文件目录:", RemoteNames)

        for file in RemoteNames:

            Local = os.path.join(LocalDir, file)

            #print("正在下载", self.ftp.nlst(file))

            try:

                self.ftp.cwd(file)

                self.ftp.cwd("..")

                if not os.path.exists(Local):

                    os.makedirs(Local)

                self.DownLoadFileTree(Local, file)

            except:

                self.DownLoadFile(Local, file)

        self.ftp.cwd("..")

        return

     

class FTPWindow(QDialog):

    def __init__(self, parent=None):

        super().__init__(parent)

        self.setWindowTitle("下载FTP文件")

        self.setFixedSize(400, 150)

 

        self.label_ftp_url = QLabel("FTP链接:", self)

        self.label_ftp_url.setGeometry(20, 20, 80, 30)

 

        self.textbox_ftp_url = QLineEdit(self)

        self.textbox_ftp_url.setGeometry(100, 20, 280, 30)

 

        self.button_download = QPushButton("下载", self)

        self.button_download.setGeometry(160, 65, 80, 30)

        self.button_download.clicked.connect(self.download_ftp_file)

 

        self.label_ftp_info = QLabel("输入包含文件名的链接下载指定文件;\n输入不包含文件名只到端口号的链接下载整个目录。", self)

        self.label_ftp_info.setGeometry(20, 110, 380, 40)

 

    def download_ftp_file(self):

        ftp_url = self.textbox_ftp_url.text()

        if ftp_url == "":

            return

        self.button_download.setEnabled(False)

        self.thread = DownloadThread(ftp_url)

        self.thread.finished.connect(self.show_message_box)

        self.thread.start()

 

    def show_message_box(self, success):

        if success:

            QMessageBox.information(self, "提示", "文件下载成功!", QMessageBox.Ok)

        else:

            QMessageBox.critical(self, "错误", "文件下载失败!", QMessageBox.Ok)

        self.button_download.setEnabled(True)

 

 

class MyWindow(QMainWindow):

    def __init__(self):

        super().__init__()

        self.setWindowTitle("文件分享")

        self.setWindowIcon(QIcon('icon.ico'))

        self.setMaximumSize(self.size())

        self.setFixedSize(400, 300)

 

        self.tcp_label = QLabel('选择传输方式:', self)

        self.tcp_label.move(20, 10)

        self.http_button = QRadioButton('HTTP', self)

        self.http_button.setChecked(True)

        self.http_button.move(150, 10)

        self.http_button.toggled.connect(self.onProtocolChanged)

        self.ftp_button = QRadioButton('FTP', self)

        self.ftp_button.move(250, 10)

        self.ftp_button.toggled.connect(self.onProtocolChanged)

 

        self.ip_label = QLabel('当前IP地址:', self)

        self.ip_label.move(20, 40)

        self.ip_text = QLabel(self.get_wired_ip(), self)

        self.ip_text.setGeometry(120, 43, 250, 25)

 

        self.port_label = QLabel('端 口 :', self)

        self.port_label.move(20, 75)

 

        self.textbox = QLineEdit(self)

        self.textbox.setGeometry(80, 75, 300, 30)

        self.textbox.setValidator(QtGui.QIntValidator(10000, 65500))

        self.textbox.setText(str(random.randint(10000, 65500))) 

 

        self.folder_label = QLabel('文件夹:', self)

        self.folder_label.setGeometry(20, 115, 50, 30)

 

        self.textfol = QLineEdit(self)

        self.textfol.setGeometry(80, 115, 220, 30)

        self.textfol.setText(QDir.currentPath())

        self.textfol.setReadOnly(True)

 

        self.folder_button = QPushButton('选择文件夹', self)

        self.folder_button.setGeometry(300, 115, 80, 30)

        self.folder_button.clicked.connect(self.onFolderClicked)

 

        self.file_label = QLabel('文 件 :', self)

        self.file_label.setGeometry(20, 155, 50, 30)

 

        self.combobox = QComboBox(self)

        self.combobox.setGeometry(80, 155, 300, 30)

 

        self.updateFileList()

        self.updateFileList()

 

        self.button = QPushButton(self)

        self.button.setText("启  动")

        self.button.setGeometry(20, 195, 360, 30)

        self.button.clicked.connect(self.show_selection)

 

        self.textboxa = QLineEdit(self)

        self.textboxa.setGeometry(20, 235, 360, 30)

        self.textboxa.mousePressEvent = self.select_text

 

        self.hidden_button = QPushButton("接收\nFTP\n文件", self)

        self.hidden_button.setVisible(False) 

        self.hidden_button.setGeometry(320, 10, 60, 55)

        self.hidden_button.clicked.connect(self.show_ftp_window)

 

        self.labela = QLabel(self)

        self.labela.setText("@hvinsion")

        self.labela.setGeometry(320, 280, 360, 20)

 

        self.labelb = QPushButton(self)

        self.labelb.setText("说明")

        self.labelb.setToolTip("帮助") 

        self.labelb.setGeometry(10, self.height() - 30, 30, 30)

        self.labelb.clicked.connect(self.open_help_window)

 

        self.help_window = HelpWindow()

 

        self.thread_pool = ThreadPoolExecutor(max_workers=5)

 

    def open_help_window(self):

        self.help_window.show()

 

    def select_text(self, event):

        self.textboxa.selectAll()

        self.textboxa.setFocus()

 

    def show_ftp_window(self):

        ftp_window = FTPWindow(self)

        ftp_window.exec_()

 

    def onProtocolChanged(self):

        if self.ftp_button.isChecked():

            self.hidden_button.setVisible(True)

        else:

            self.hidden_button.setVisible(False)

 

    def onFolderClicked(self):

        m = QFileDialog.getExistingDirectory(self, "选取文件夹", QDir.currentPath())

        self.textfol.setText(m)

        self.updateFileList()

 

    def updateFileList(self):

        folder_path = self.textfol.text()

        file_list = QDir(folder_path).entryList(QDir.Files)

        self.combobox.clear()

        self.combobox.addItems(file_list)

 

    def get_wired_ip(self):

        try:

            default_gateway = netifaces.gateways()['default']

            if default_gateway and netifaces.AF_INET in default_gateway:

                routingNicName = default_gateway[netifaces.AF_INET][1]

                for interface in netifaces.interfaces():

                    if interface == routingNicName:

                        routingIPAddr = netifaces.ifaddresses(interface).get(netifaces.AF_INET)

                        if routingIPAddr:

                            return routingIPAddr[0]['addr']

        except (KeyError, IndexError):

            pass

        return "未找到物理网卡IP"

 

    def start_flask_server(self):

        app = Flask(__name__)

 

        @app.route('/download/<filename>', methods=['GET'])

        def download_file(filename):

            file_path = os.path.join(self.textfol.text(), filename)

            return send_file(file_path, as_attachment=True)

 

        port = int(self.textbox.text())

        self.textbox.setText(str(random.randint(10000, 65500)))

        app.run(host='0.0.0.0', port=port, threaded=True)

         

 

    def start_ftp_server(self):

        authorizer = DummyAuthorizer()

        authorizer.add_user('a', 'a', self.textfol.text(), perm='elradfmwM')

 

        class CustomFTPHandler(FTPHandler):

            def on_file_received(self, file):

                pass

            def on_file_deleted(self, file):

                pass

            def on_rename(self, old_file, new_file):

                pass

 

        handler = CustomFTPHandler

        handler.authorizer = authorizer

 

        address = ('0.0.0.0', int(self.textbox.text()))

 

        server = ThreadedFTPServer(address, handler)

        self.thread_pool.submit(server.serve_forever)

        self.textbox.setText(str(random.randint(10000, 65500)))

 

    def show_selection(self):

        ip_address = self.get_wired_ip()

        port_text = self.textbox.text()

        if int(port_text)<10000:

            QMessageBox.critical(self, "警告", "请勿使用10000以下端口号!", QMessageBox.Ok)

            self.textbox.setText(str(random.randint(10000, 65500)))

            return

        selected_file = self.combobox.currentText()

        if self.http_button.isChecked():

            self.thread_pool.submit(self.start_flask_server)

            self.textboxa.setText("http://" + ip_address + ":" + port_text + "/download/" + selected_file)

        elif self.ftp_button.isChecked():

            self.thread_pool.submit(self.start_ftp_server)

            self.textboxa.setText("ftp://a:a@" + ip_address + ":" + port_text + "/" + selected_file)

        else:

            QMessageBox.warning(self, "警告", "请选择传输方式!", QMessageBox.Ok)

 

if __name__ == "__main__":

    app = QApplication(sys.argv)

    win = MyWindow()

    win.show()

    sys.exit(app.exec_())


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计