PYQT5+pycharm将C++写的TCP服务器和客户端通信实现 您所在的位置:网站首页 qt文件传输工具tcp PYQT5+pycharm将C++写的TCP服务器和客户端通信实现

PYQT5+pycharm将C++写的TCP服务器和客户端通信实现

2024-07-16 06:49| 来源: 网络整理| 查看: 265

PYQT5+pycharm将C++写的TCP服务器和客户端通信复刻实现 摘要:

用pyqt5+pycharm开发环境实现c++在QT环境下的程序代码,实现局域网TCP文件传输工具并带界面。 参考C++代码文献地址见文章底。

目录

程序功能

代码设计 1.服务端 2.客户端

1.程序功能

详细见源码:https://download.csdn.net/download/qq_42307630/21074738 1.在同一局域网内的两个设备,基于tcp网络编程,实现可靠的、高速的文件传输,并且实时显示传输进度和速度;采用客户端、服务端形式,满足双向传输;具有可扩展性、可移植性。实测传输速度可达到9Mb/s。 服务端 监听端口:当计算机网络底层收到tcp信息时,通过端口传递给相应的程序进行处理,也就是说一个端口只能被一个应用程序使用,但一个应用程序可以使用多个端口。 选择监听端口(为了避免已被其他程序使用,可设大一点),点击打开服务器,可更改接收文件的保存路径,等到客户端连接,客户端连接成功后,可用鼠标拖动文件至中间空白处,即可将文件传输到客户端。 在这里插入图片描述 客户端 输入服务端的ip地址(下面的是我的ip,请根据服务端本地ip修改)和监听的端口号,服务端的ip地址查看:右击电脑右下角网络图标->打开网络和共享中心->本地连接->详细信息->IP4地址,正确填写后点击连接服务器,服务器端将显示客户端已连接,接下来就可以开始文件传输了 在这里插入图片描述 在这里插入图片描述

2.代码设计

服务端

#!/usr/bin/env python # coding=utf-8 from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import QFileDialog, QMessageBox, QMainWindow from PyQt5.QtCore import QFile, QFileInfo, QTime, QTimer, QByteArray, pyqtSlot, QDir, QIODevice, QDataStream from PyQt5.QtNetwork import QTcpSocket from PyQt5.QtNetwork import QTcpServer, QHostAddress from PyQt5.QtNetwork import QNetworkInterface from Ui_mainwindow import Ui_MainWindow import array class eSTATUS: ST_IDLE = 0 ST_SENDING = 1 ST_RECING = 2 class MyServer(QMainWindow): def __init__(self): super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.tcpServer = QTcpServer() self.tcpServer.newConnection.connect(self.do_connect) # self.socket =QTcpSocket() self.clientConnection = QTcpSocket() self.localFile = QFile() self.localFile = None #self.loadSize = 64*1024 # 缓冲区大小 self.totalBytes = 0 self.bytesWriten = 0 self.bytesTowrite = 0 self.outblock = QByteArray() self.numBytes = 0 self.filename = None self.fileSavePath = 'C:/' self.bytesReceived = 0 self.status = eSTATUS.ST_IDLE self.temp = '保存路径:'+ self.fileSavePath self.ui.label_5.setText(self.temp) # 设置进度条 self.ui.progressBar.setValue(0) self.ui.progressBar.setRange(0, 100) self.ui.textEdit.setEnabled(True) self.ui.lineEdit.setDisabled(True) self.counter = QTime() self.timer = QTimer() self.timer.stop() self.timer.timeout.connect(self.second_task) @pyqtSlot() def on_textEdit_textChanged(self): # 测试ok!! filepath = self.ui.textEdit.toPlainText() if not len(filepath): return if self.clientConnection == None: QMessageBox.warning(self,'警告', '未有客户端连接。') self.ui.textEdit.clear() return if self.ui.label_3.text() == '未打开服务器': QMessageBox.warning(self, '警告', '未打开服务器。') self.ui.textEdit.clear() return if self.status != eSTATUS.ST_IDLE: QMessageBox.warning(self, "警告", "正在输入文件。") self.ui.textEdit.clear() return print('服务端选择发送的是:', filepath) file_path = filepath[8:] print(file_path) if not QFileInfo(file_path).isFile(): print('发送的不是文件。') QMessageBox.warning(self, '警告', "请选择单个文件。") self.ui.textEdit.clear() return self.sendFile(file_path) self.ui.textEdit.clear() def do_connect(self): #测试OK!! self.clientConnection = self.tcpServer.nextPendingConnection() #将下一个挂起的连接作为已连接的QTcpSocket对象返回。 self.clientConnection.disconnected.connect(self.do_disconnect) self.clientConnection.readyRead.connect(self.readMessage) self.ui.label_3.setText('客户已连接') @pyqtSlot() def sendFile(self, filepath): # 测试ok!! self.localFile = QFile(filepath) print(type(self.localFile.read(64))) file_info = QFileInfo(filepath) file_name = file_info.fileName() self.filename = file_name if not self.localFile.open(QIODevice.ReadOnly): print('服务端无法读取发送文件') return else: temp = '正在发送'+file_name self.ui.label_3.setText(temp) print(f'服务端开始发送文件: {file_name} 大小:{self.localFile.size()}') # 开始发送文件 self.bytesTowrite = self.totalBytes = self.localFile.size() # 总字节数 self.loadSize = 64*1024 self.status = eSTATUS.ST_SENDING # 线程状态 self.counter.start() #开始计时 self.timer.start(1000) #计时器工作 fileinfo = "fliename\ %s\ filze\ %d" % (file_name, self.totalBytes) fileinfoBytes = fileinfo.encode("utf-8") #zijie = len(fileinfoBytes) Startframe = "@newfile\ %0.4d" % (len(fileinfoBytes)) StartframeBytes = Startframe.encode("utf-8") print(fileinfo) print(Startframe) # 先发送文件信息 size1 = self.clientConnection.write(StartframeBytes) size2 = self.clientConnection.write(fileinfoBytes) print(size1, size2) self.clientConnection.bytesWritten.connect(self.updateClientProgress) # 更新客户端进程 def updateClientProgress(self): if self.bytesTowrite > 0: self.outblock = self.localFile.read(min(self.bytesTowrite, self.loadSize)) self.bytesWriten = self.clientConnection.write(self.outblock) self.bytesTowrite -= self.bytesWriten self.numBytes += self.bytesWriten setRate = int((self.numBytes / self.totalBytes) * 100) self.ui.progressBar.setValue(setRate) else: self.second_task() self.timer.stop() self.totalBytes = 0 self.bytesWriten = 0 self.bytesTowrite = 0 self.status = eSTATUS.ST_IDLE self.localFile.close() self.ui.progressBar.setValue(100) self.ui.label_3.setText('发送成功') print(f'{self.filename}文件发送成功') self.clientConnection.bytesWritten.disconnect(self.updateClientProgress)

客户端

from PyQt5.QtWidgets import QFileDialog, QMessageBox, QMainWindow from PyQt5.QtCore import QIODevice, QFile, QFileInfo, QDir, QTime, QTimer, QByteArray, pyqtSlot from PyQt5.QtNetwork import QTcpServer, QTcpSocket, QHostAddress from Ui_client import ClientWindow class eSTATUS: ST_IDLE = 0 ST_SENDING = 1 ST_RECING = 2 class MyClient(QMainWindow): def __init__(self): super(MyClient, self).__init__() self.ui = ClientWindow() self.ui.setupUi(self) self.tcpClient = QTcpSocket() self.tcpClient.readyRead.connect(self.readMessage) self.tcpClient.disconnected.connect(self.do_disconnect) self.tcpClient.error.connect(self.ErrorOccurred) @pyqtSlot() def on_pushButton_clicked(self): if self.ui.pushButton.text()=='断开连接': self.do_disconnect() else: #建立连接 hostAddress = QHostAddress(self.ui.lineEdit.text()) tcpPort = int(self.ui.lineEdit_2.text()) self.tcpClient.abort() self.tcpClient.connectToHost(hostAddress, tcpPort) self.ui.label_4.setText('已连接服务器') self.ui.pushButton.setText('断开连接') self.ui.lineEdit.setDisabled(True) self.ui.lineEdit_2.setDisabled(True) self.ui.textEdit.setDisabled(False) @pyqtSlot() def readMessage(self): useTime = self.count.elapsed() if self.status == eSTATUS.ST_IDLE: FrameHead = self.tcpClient.read(14).decode('utf-8').strip() print(FrameHead) filelist = FrameHead.split('\ ') print(filelist) fileinfolen = int(filelist[1]) print(fileinfolen) fileinfo = self.tcpClient.read(fileinfolen).decode('utf-8') filelist1 = fileinfo.split('\ ') print(filelist1) self.filename = filelist1[1] filesize = filelist1[3] print(self.filename, filesize) # file_new = self.fileSavePath + self.filename self.localfile = QFile(self.filename) self.totalBytes = int(filesize) if not self.localfile.open(QIODevice.WriteOnly): print('服务端文件创建失败', self.filename) self.do_disconnect() return self.status = eSTATUS.ST_RECING self.count.start() self.timer.start(1000) self.ui.progressBar.setValue(0) self.ui.label_4.setText('正在接受' + self.filename) print(f'服务端开始接收文件:{self.filename}大小:{self.totalBytes}') return self.bytesReceived += self.tcpClient.bytesAvailable() self.inBock = self.tcpClient.readAll() self.localfile.write(self.inBock) self.inBock.resize(0) downedRate = (self.bytesReceived / self.totalBytes) * 100 self.ui.progressBar.setValue(downedRate) if self.bytesReceived == self.totalBytes: self.second_task() self.timer.stop() self.localfile.close() self.bytesReceived = 0 self.status = eSTATUS.ST_IDLE self.ui.label_4.setText('接收完成。') self.ui.progressBar.setValue(100) print(f'接收完毕{self.localfile.fileName()}') print(f'用时:{useTime / 1000}s') directory = QDir() directory.cd(self.fileSavePath) # 进入目录 self.localfile.copy(self.fileSavePath + self.filename) self.localfile.close() def ErrorOccurred(self): QMessageBox.warning(self, '警告', self.tcpClient.errorString()) self.do_disconnect() return

详细见源码https://download.csdn.net/download/qq_42307630/21074738

参考文献 [1]:https://blog.csdn.net/weixin_42653531/article/details/103880917



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有