博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PyQt5综合实践—TCP服务器
阅读量:6468 次
发布时间:2019-06-23

本文共 10251 字,大约阅读时间需要 34 分钟。

目的:实现一个可以用于接收和发送文本的TCP服务器。

思路 :

1. 两个QLineEdit用于服务器ip和port的输入,同时会限制ip和port的输入。

2. 一个QPushButton,点击后开始“监听”,并把连接的过程放到一个线程thread中,这样不会在等待连接的过程中造成程序阻塞。

3. 一个QlineEdit用于显示连接后的客户端地址和端口信息。

4. 再来一个QPushButton,关闭当前连接,如果当前连接不存在,则提示“没有连接”。

5. 增加两个QLineEdit用于输入发送数据,和显示接收数据。

 

1. 这里直接使用QtDesginer布局,配合GroupBox控件摆了5个QLineEdit和3个QPushButton ,保存为testGUI.ui 。

 

2. 用PyUIC转化为python代码,生成文件testGUI.py:

1 # -*- coding: utf-8 -*-  2   3 # Form implementation generated from reading ui file 'testGUi.ui'  4 #  5 # Created by: PyQt5 UI code generator 5.11.3  6 #  7 # WARNING! All changes made in this file will be lost!  8   9 from PyQt5 import QtCore, QtGui, QtWidgets 10  11 class Ui_MainWindow(object): 12     def setupUi(self, MainWindow): 13         MainWindow.setObjectName("MainWindow") 14         MainWindow.resize(547, 214) 15         sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) 16         sizePolicy.setHorizontalStretch(0) 17         sizePolicy.setVerticalStretch(0) 18         sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth()) 19         MainWindow.setSizePolicy(sizePolicy) 20         self.centralwidget = QtWidgets.QWidget(MainWindow) 21         self.centralwidget.setObjectName("centralwidget") 22         self.groupBox = QtWidgets.QGroupBox(self.centralwidget) 23         self.groupBox.setGeometry(QtCore.QRect(10, 10, 331, 41)) 24         self.groupBox.setObjectName("groupBox") 25         self.listenButton = QtWidgets.QPushButton(self.groupBox) 26         self.listenButton.setGeometry(QtCore.QRect(260, 14, 61, 21)) 27         sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) 28         sizePolicy.setHorizontalStretch(1) 29         sizePolicy.setVerticalStretch(0) 30         sizePolicy.setHeightForWidth(self.listenButton.sizePolicy().hasHeightForWidth()) 31         self.listenButton.setSizePolicy(sizePolicy) 32         self.listenButton.setObjectName("listenButton") 33         self.layoutWidget = QtWidgets.QWidget(self.groupBox) 34         self.layoutWidget.setGeometry(QtCore.QRect(10, 13, 241, 22)) 35         self.layoutWidget.setObjectName("layoutWidget") 36         self.horizontalLayout = QtWidgets.QHBoxLayout(self.layoutWidget) 37         self.horizontalLayout.setContentsMargins(0, 0, 0, 0) 38         self.horizontalLayout.setObjectName("horizontalLayout") 39         self.ipLabel = QtWidgets.QLabel(self.layoutWidget) 40         self.ipLabel.setObjectName("ipLabel") 41         self.horizontalLayout.addWidget(self.ipLabel) 42         self.ipLineEdit = QtWidgets.QLineEdit(self.layoutWidget) 43         self.ipLineEdit.setObjectName("ipLineEdit") 44         self.horizontalLayout.addWidget(self.ipLineEdit) 45         self.portLabel = QtWidgets.QLabel(self.layoutWidget) 46         self.portLabel.setObjectName("portLabel") 47         self.horizontalLayout.addWidget(self.portLabel) 48         self.portLineEdit = QtWidgets.QLineEdit(self.layoutWidget) 49         self.portLineEdit.setObjectName("portLineEdit") 50         self.horizontalLayout.addWidget(self.portLineEdit) 51         self.horizontalLayout.setStretch(0, 1) 52         self.horizontalLayout.setStretch(1, 4) 53         self.horizontalLayout.setStretch(2, 1) 54         self.horizontalLayout.setStretch(3, 2) 55         self.groupBox_2 = QtWidgets.QGroupBox(self.centralwidget) 56         self.groupBox_2.setGeometry(QtCore.QRect(350, 10, 181, 41)) 57         self.groupBox_2.setObjectName("groupBox_2") 58         self.connectLineEdit = QtWidgets.QLineEdit(self.groupBox_2) 59         self.connectLineEdit.setGeometry(QtCore.QRect(10, 13, 111, 19)) 60         self.connectLineEdit.setReadOnly(True) 61         self.connectLineEdit.setObjectName("connectLineEdit") 62         self.disconnectButton = QtWidgets.QPushButton(self.groupBox_2) 63         self.disconnectButton.setGeometry(QtCore.QRect(130, 12, 41, 21)) 64         sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) 65         sizePolicy.setHorizontalStretch(1) 66         sizePolicy.setVerticalStretch(0) 67         sizePolicy.setHeightForWidth(self.disconnectButton.sizePolicy().hasHeightForWidth()) 68         self.disconnectButton.setSizePolicy(sizePolicy) 69         self.disconnectButton.setObjectName("disconnectButton") 70         self.sendLineEdit = QtWidgets.QLineEdit(self.centralwidget) 71         self.sendLineEdit.setGeometry(QtCore.QRect(60, 70, 281, 31)) 72         self.sendLineEdit.setObjectName("sendLineEdit") 73         self.sendButton = QtWidgets.QPushButton(self.centralwidget) 74         self.sendButton.setGeometry(QtCore.QRect(360, 70, 75, 31)) 75         self.sendButton.setObjectName("sendButton") 76         self.recvLineEdit = QtWidgets.QLineEdit(self.centralwidget) 77         self.recvLineEdit.setGeometry(QtCore.QRect(60, 120, 281, 31)) 78         self.recvLineEdit.setObjectName("recvLineEdit") 79         self.label = QtWidgets.QLabel(self.centralwidget) 80         self.label.setGeometry(QtCore.QRect(20, 80, 31, 16)) 81         self.label.setObjectName("label") 82         self.label_2 = QtWidgets.QLabel(self.centralwidget) 83         self.label_2.setGeometry(QtCore.QRect(20, 130, 31, 16)) 84         self.label_2.setObjectName("label_2") 85         self.groupBox_2.raise_() 86         self.groupBox.raise_() 87         self.sendLineEdit.raise_() 88         self.sendButton.raise_() 89         self.recvLineEdit.raise_() 90         self.label.raise_() 91         self.label_2.raise_() 92         MainWindow.setCentralWidget(self.centralwidget) 93         self.menubar = QtWidgets.QMenuBar(MainWindow) 94         self.menubar.setGeometry(QtCore.QRect(0, 0, 547, 23)) 95         self.menubar.setObjectName("menubar") 96         MainWindow.setMenuBar(self.menubar) 97         self.statusbar = QtWidgets.QStatusBar(MainWindow) 98         self.statusbar.setObjectName("statusbar") 99         MainWindow.setStatusBar(self.statusbar)100 101         self.retranslateUi(MainWindow)102         QtCore.QMetaObject.connectSlotsByName(MainWindow)103 104     def retranslateUi(self, MainWindow):105         _translate = QtCore.QCoreApplication.translate106         MainWindow.setWindowTitle(_translate("MainWindow", "Test Tool"))107         self.groupBox.setTitle(_translate("MainWindow", "网络配置"))108         self.listenButton.setText(_translate("MainWindow", "开始监听"))109         self.ipLabel.setText(_translate("MainWindow", "IP地址:"))110         self.portLabel.setText(_translate("MainWindow", "端口:"))111         self.groupBox_2.setTitle(_translate("MainWindow", "当前连接"))112         self.disconnectButton.setText(_translate("MainWindow", "断开"))113         self.sendButton.setText(_translate("MainWindow", "发送"))114         self.label.setText(_translate("MainWindow", "发送:"))115         self.label_2.setText(_translate("MainWindow", "接收:"))
View Code

3. 继承testGUI,实现主要功能:

1 import sys 2 import socket 3 import threading 4 from PyQt5.QtCore import QRegExp 5 from PyQt5.QtGui import QIntValidator,QRegExpValidator 6 from PyQt5.QtWidgets import QApplication,QMainWindow 7 from test.testGUi import Ui_MainWindow 8  9 class TestGUI(Ui_MainWindow):10 11     def __init__(self, MainWindow):12         """13         初始化界面 ,连接槽函数,以及设置校验器14         """15         self.setupUi(MainWindow)16         self.connect_slot()17         self.server_validator()18 19     def start_tcp_server(self):20         # 设置 “开始监听” 按钮不可用21         self.listenButton.setDisabled(True)22         # 实例化一个socket23         self.sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)24         try:25             ipText = self.ipLineEdit.text()26             portValue = int(self.portLineEdit.text())27             self.sock.bind((ipText,portValue))28         except Exception as e:29             print("请检查ip和端口号")30             print(e)31         else:32             self.sock.listen(1)33             # 创建一个进程,用于处理socket连接和接收数据34             server_th = threading.Thread(target=self.tcp_connect_concurrency)35             server_th.start()36             print("正在监听")37 38     # 进程函数39     def tcp_connect_concurrency(self):40         try:41             connect ,address = self.sock.accept()42         except Exception as e:43             print(e)44         self.base_connect = connect45         connect_address = address[0] + ":" + str(address[1])46         self.connectLineEdit.setText(connect_address)47         while True:48             recv_msg = self.base_connect.recv(1024)49             self.recvLineEdit.setText(recv_msg.decode('utf-8'))50 51     def tcp_close(self):52         """53         点击'disconnect'按钮,断开当前连接54         """55         if self.listenButton.isEnabled()==False:56             self.listenButton.setDisabled(False)57         try:58             self.base_connect.close()59             self.connectLineEdit.setText("")60         except AttributeError as e:61             pass62         except Exception as e:63             print(e)64 65     def send_text(self):66         """67         点击“发送”发送数据/文本68         """69         send_msg = self.sendLineEdit.text()70         self.base_connect.send(send_msg.encode('utf-8'))71 72     def server_validator(self):73         """74         设置 ip 和 port 文本输入框的限制75         """76         ipValidator = QRegExpValidator(QRegExp('^((2[0-4]\d|25[0-5]|\d?\d|1\d{2})\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$'))77         portValidator = QIntValidator(0,65535)78         self.ipLineEdit.setValidator(ipValidator)79         self.portLineEdit.setValidator(portValidator)80         self.ipLineEdit.setPlaceholderText("请输入ip地址")81         self.portLineEdit.setPlaceholderText("端口")82 83     def connect_slot(self):84         """连接各控件的槽函数"""85         self.listenButton.clicked.connect(self.start_tcp_server)86         self.disconnectButton.clicked.connect(self.tcp_close)87         self.sendButton.clicked.connect(self.send_text)88 89 if __name__ == '__main__':90     app = QApplication(sys.argv)91     mainWindow = QMainWindow()92     ui = TestGUI(mainWindow)93     mainWindow.show()94     sys.exit(app.exec_())
View Code

4. 运行后的结果:

  1)先运行mainGUI.py ,输入如下IP地址和端口号,点击“开始监听”,然后运行server.py,就能获取到连接了。

        

  2)发送文本框输入"你好",点击“发送” ,client收到发送的内容,并发送文本"Hi"

        

   3)点击“断开”可以断开当前连接。

转载于:https://www.cnblogs.com/jxu25/p/11018321.html

你可能感兴趣的文章
ImageOptim-无损图片压缩Mac版
查看>>
12 Go语言map底层浅析
查看>>
vue-resumer 项目中 element-ui 遇到的 textarea autosize 问题
查看>>
以主干开发作为持续交付的基础
查看>>
Tech UP——EGO北京分会成立啦
查看>>
PHP扩展库PEAR被攻击,近半年下载者或被影响
查看>>
传统运维团队转型应该注意哪些问题?
查看>>
JavaScript函数(二)
查看>>
Airbnb改进部署管道安全性,规范部署顺序
查看>>
腾讯最大规模裁撤中层干部,让贤年轻人
查看>>
当我们谈性能的时候,我们实际上在谈什么?
查看>>
Spring Boot 2.0将会增强Actuator端点的特性
查看>>
i4o开源项目增强LINQ索引功能
查看>>
蔡超:入门 Go 语言必须跨越的五个思维误区
查看>>
使用Akka Actor和Java 8构建反应式应用
查看>>
curl常用命令详解
查看>>
saltstack 添加计划任务
查看>>
Puppet module命令参数介绍(六)
查看>>
《UNIX网络编程》中第一个timer_server的例子
查看>>
CISCO 路由器(4)
查看>>