PyQt5综合实践—TCP服务器

Stella981
• 阅读 995

目的:实现一个可以用于接收和发送文本的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 。

 PyQt5综合实践—TCP服务器

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

PyQt5综合实践—TCP服务器 PyQt5综合实践—TCP服务器

  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.translate
106         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,实现主要功能:

PyQt5综合实践—TCP服务器 PyQt5综合实践—TCP服务器

 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         # 实例化一个socket
23         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 = connect
45         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             pass
62         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,就能获取到连接了。

        PyQt5综合实践—TCP服务器

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

        PyQt5综合实践—TCP服务器

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

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Stella981 Stella981
3年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Stella981 Stella981
3年前
Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法
Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法参考文章:(1)Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.codeprj.com%2Fblo
Wesley13 Wesley13
3年前
34.TCP取样器
阅读文本大概需要3分钟。1、TCP取样器的作用   TCP取样器作用就是通过TCP/IP协议来连接服务器,然后发送数据和接收数据。2、TCP取样器详解!(https://oscimg.oschina.net/oscnet/32a9b19ba1db00f321d22a0f33bcfb68a0d.png)TCPClien
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这