python服务器qt客户端_python3+PyQt5 创建多线程网络应用-TCP客户端和TCP服务器实例...

本文在上文的基础上重新实现支持多线程的服务器。

以下为TCP客户端的程序代码:

#!/usr/bin/env python3

import sys

from PyQt5.QtCore import (QByteArray, QDataStream, QDate, QIODevice,

QRegExp, Qt)

from PyQt5.QtWidgets import (QApplication, QDateEdit, QFrame, QGridLayout,

QHBoxLayout, QLabel, QLineEdit, QPushButton,

QWidget)

from PyQt5.QtGui import QRegExpValidator

from PyQt5.QtNetwork import (QTcpSocket,)

MAC = True

try:

from PyQt5.QtGui import qt_mac_set_native_menubar

except ImportError:

MAC = False

PORT = 9407

SIZEOF_UINT16 = 2

class BuildingServicesClient(QWidget):

def __init__(self, parent=None):

super(BuildingServicesClient, self).__init__(parent)

self.socket = QTcpSocket()

self.nextBlockSize = 0

self.request = None

roomLabel = QLabel("&Room")

self.roomEdit = QLineEdit()

roomLabel.setBuddy(self.roomEdit)

regex = QRegExp(r"[0-9](?:0[1-9]|[12][0-9]|3[0-4])")

self.roomEdit.setValidator(QRegExpValidator(regex, self))

self.roomEdit.setAlignment(Qt.AlignRight|Qt.AlignVCenter)

dateLabel = QLabel("&Date")

self.dateEdit = QDateEdit()

dateLabel.setBuddy(self.dateEdit)

self.dateEdit.setAlignment(Qt.AlignRight|Qt.AlignVCenter)

self.dateEdit.setDate(QDate.currentDate().addDays(1))

self.dateEdit.setDisplayFormat("yyyy-MM-dd")

responseLabel = QLabel("Response")

self.responseLabel = QLabel()

self.responseLabel.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken)

self.bookButton = QPushButton("&Book")

self.bookButton.setEnabled(False)

self.unBookButton = QPushButton("&Unbook")

self.unBookButton.setEnabled(False)

quitButton = QPushButton("&Quit")

if not MAC:

self.bookButton.setFocusPolicy(Qt.NoFocus)

self.unBookButton.setFocusPolicy(Qt.NoFocus)

buttonLayout = QHBoxLayout()

buttonLayout.addWidget(self.bookButton)

buttonLayout.addWidget(self.unBookButton)

buttonLayout.addStretch()

buttonLayout.addWidget(quitButton)

layout = QGridLayout()

layout.addWidget(roomLabel, 0, 0)

layout.addWidget(self.roomEdit, 0, 1)

layout.addWidget(dateLabel, 0, 2)

layout.addWidget(self.dateEdit, 0, 3)

layout.addWidget(responseLabel, 1, 0)

layout.addWidget(self.responseLabel, 1, 1, 1, 3)

layout.addLayout(buttonLayout, 2, 1, 1, 4)

self.setLayout(layout)

self.socket.connected.connect(self.sendRequest)

self.socket.readyRead.connect(self.readResponse)

self.socket.disconnected.connect(self.serverHasStopped)

#self.connect(self.socket,

# SIGNAL("error(QAbstractSocket::SocketError)"),

# self.serverHasError)

self.socket.error.connect(self.serverHasError)

self.roomEdit.textEdited.connect(self.updateUi)

self.dateEdit.dateChanged.connect(self.updateUi)

self.bookButton.clicked.connect(self.book)

self.unBookButton.clicked.connect(self.unBook)

quitButton.clicked.connect(self.close)

self.setWindowTitle("Building Services")

def updateUi(self):

enabled = False

if (self.roomEdit.text() and

self.dateEdit.date() > QDate.currentDate()):

enabled = True

if self.request is not None:

enabled = False

self.bookButton.setEnabled(enabled)

self.unBookButton.setEnabled(enabled)

def closeEvent(self, event):

self.socket.close()

event.accept()

def book(self):

self.issueRequest("BOOK", self.roomEdit.text(),

self.dateEdit.date())

def unBook(self):

self.issueRequest("UNBOOK", self.roomEdit.text(),

self.dateEdit.date())

def issueRequest(self, action, room, date):

self.request = QByteArray()

stream = QDataStream(self.request, QIODevice.WriteOnly)

stream.setVersion(QDataStream.Qt_5_7)

stream.writeUInt16(0)

stream.writeQString(action)

stream.writeQString(room)

stream << date

stream.device().seek(0)

stream.writeUInt16(self.request.size() - SIZEOF_UINT16)#overwrite seek(0)

self.updateUi()

if self.socket.isOpen():

self.socket.close()

self.responseLabel.setText("Connecting to server...")

self.socket.connectToHost("localhost", PORT)

def sendRequest(self):

self.responseLabel.setText("Sending request...")

self.nextBlockSize = 0

self.socket.write(self.request)

self.request = None

def readResponse(self):

stream = QDataStream(self.socket)

stream.setVersion(QDataStream.Qt_5_7)

while True:

if self.nextBlockSize == 0:

if self.socket.bytesAvailable() < SIZEOF_UINT16:

break

self.nextBlockSize = stream.readUInt16()

if self.socket.bytesAvailable() < self.nextBlockSize:

break

action = ""

room = ""

date = QDate()

#stream >> action >> room

action=stream.readQString()

room=stream.readQString()

if action != "ERROR":

stream >> date

if action == "ERROR":

msg = "Error: {0}".format(room)

elif action == "BOOK":

msg = "Booked room {0} for {1}".format(room,date.toString(Qt.ISODate))

elif action == "UNBOOK":

msg = "Unbooked room {0} for {1}".format(room,date.toString(Qt.ISODate))

self.responseLabel.setText(msg)

self.updateUi()

self.nextBlockSize = 0

def serverHasStopped(self):

self.responseLabel.setText(

"Error: Connection closed by server")

self.socket.close()

def serverHasError(self, error):

self.responseLabel.setText("Error: {0}".format(self.socket.errorString()))

self.socket.close()

app = QApplication(sys.argv)

form = BuildingServicesClient()

form.show()

app.exec_()

以下为TCP服务端的程序代码:

#!/usr/bin/env python3

import bisect

import collections

import sys

from PyQt5.QtCore import (QByteArray, QDataStream, QDate, QReadWriteLock, QThread,QIODevice, Qt)

from PyQt5.QtWidgets import (QApplication, QMessageBox, QPushButton)

from PyQt5.QtNetwork import (QAbstractSocket,QHostAddress, QTcpServer, QTcpSocket)

PORT = 9407

SIZEOF_UINT16 = 2

MAX_BOOKINGS_PER_DAY = 5

# Key = date, value = list of room IDs

Bookings = collections.defaultdict(list)

def printBookings():

for key in sorted(Bookings):

print(key, Bookings[key])

print()

class Thread(QThread):

lock = QReadWriteLock()

def __init__(self, socketId, parent):

super(Thread, self).__init__(parent)

self.socketId = socketId

def run(self):

socket = QTcpSocket()

if not socket.setSocketDescriptor(self.socketId):

#self.emit(SIGNAL("error(int)"), socket.error())

self.error.connect(socket.error)

return

while socket.state() == QAbstractSocket.ConnectedState:

nextBlockSize = 0

stream = QDataStream(socket)

stream.setVersion(QDataStream.Qt_5_7)

if (socket.waitForReadyRead() and

socket.bytesAvailable() >= SIZEOF_UINT16):

nextBlockSize = stream.readUInt16()

else:

self.sendError(socket, "Cannot read client request")

return

if socket.bytesAvailable() < nextBlockSize:

if (not socket.waitForReadyRead(60000) or

socket.bytesAvailable() < nextBlockSize):

self.sendError(socket, "Cannot read client data")

return

action = ""

room = ""

date = QDate()

action=stream.readQString()

if action in ("BOOK", "UNBOOK"):

room=stream.readQString()

stream >> date

try:

Thread.lock.lockForRead()

bookings = Bookings.get(date.toPyDate())

finally:

Thread.lock.unlock()

uroom = str(room)

if action == "BOOK":

newlist = False

try:

Thread.lock.lockForRead()

if bookings is None:

newlist = True

finally:

Thread.lock.unlock()

if newlist:

try:

Thread.lock.lockForWrite()

bookings = Bookings[date.toPyDate()]

finally:

Thread.lock.unlock()

error = None

insert = False

try:

Thread.lock.lockForRead()

if len(bookings) < MAX_BOOKINGS_PER_DAY:

if uroom in bookings:

error = "Cannot accept duplicate booking"

else:

insert = True

else:

error = "{0} is fully booked".format(date.toString(Qt.ISODate))

finally:

Thread.lock.unlock()

if insert:

try:

Thread.lock.lockForWrite()

bisect.insort(bookings, uroom)

finally:

Thread.lock.unlock()

self.sendReply(socket, action, room, date)

else:

self.sendError(socket, error)

elif action == "UNBOOK":

error = None

remove = False

try:

Thread.lock.lockForRead()

if bookings is None or uroom not in bookings:

error = "Cannot unbook nonexistent booking"

else:

remove = True

finally:

Thread.lock.unlock()

if remove:

try:

Thread.lock.lockForWrite()

bookings.remove(uroom)

finally:

Thread.lock.unlock()

self.sendReply(socket, action, room, date)

else:

self.sendError(socket, error)

else:

self.sendError(socket, "Unrecognized request")

socket.waitForDisconnected()

try:

Thread.lock.lockForRead()

printBookings()

finally:

Thread.lock.unlock()

def sendError(self, socket, msg):

reply = QByteArray()

stream = QDataStream(reply, QIODevice.WriteOnly)

stream.setVersion(QDataStream.Qt_5_7)

stream.writeUInt16(0)

stream.writeQString("ERROR")

stream.writeQString(msg)

stream.device().seek(0)

stream.writeUInt16(reply.size() - SIZEOF_UINT16)

socket.write(reply)

def sendReply(self, socket, action, room, date):

reply = QByteArray()

stream = QDataStream(reply, QIODevice.WriteOnly)

stream.setVersion(QDataStream.Qt_5_7)

stream.writeUInt16(0)

stream.writeQString(action)

stream.writeQString(room)

stream<

stream.device().seek(0)

stream.writeUInt16(reply.size() - SIZEOF_UINT16)

socket.write(reply)

class TcpServer(QTcpServer):

def __init__(self, parent=None):

super(TcpServer, self).__init__(parent)

def incomingConnection(self, socketId):

thread = Thread(socketId, self)

#self.connect(thread, SIGNAL("finished()"),

# thread, SLOT("deleteLater()"))

thread.finished.connect(thread.deleteLater)

thread.start()

class BuildingServicesDlg(QPushButton):

def __init__(self, parent=None):

super(BuildingServicesDlg, self).__init__(

"&Close Server", parent)

self.setWindowFlags(Qt.WindowStaysOnTopHint)

self.loadBookings()

self.tcpServer = TcpServer(self)

if not self.tcpServer.listen(QHostAddress("0.0.0.0"), PORT):

QMessageBox.critical(self, "Building Services Server","Failed to start server: {0}".format(self.tcpServer.errorString()))

self.close()

return

self.clicked.connect(self.close)

font = self.font()

font.setPointSize(24)

self.setFont(font)

self.setWindowTitle("Building Services Server")

def loadBookings(self):

# Generate fake data

import random

today = QDate.currentDate()

for i in range(10):

date = today.addDays(random.randint(7, 60))

for j in range(random.randint(1, MAX_BOOKINGS_PER_DAY)):

# Rooms are 001..534 excl. 100, 200, ..., 500

floor = random.randint(0, 5)

room = random.randint(1, 34)

bookings = Bookings[date.toPyDate()]

if len(bookings) >= MAX_BOOKINGS_PER_DAY:

continue

bisect.insort(bookings, "{0:1d}{1:02d}".format(

floor, room))

printBookings()

app = QApplication(sys.argv)

form = BuildingServicesDlg()

form.show()

form.move(0, 0)

app.exec_()

以上这篇python3+PyQt5 创建多线程网络应用-TCP客户端和TCP服务器实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/304704.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

巧合?模仿还是抄袭?水木年华的《秋日恋歌》和Lube 乐队的《Pozovi Menya Tiho Po Imeni》...

今天听到了俄罗斯的Lube 乐队的《Pozovi Menya Tiho Po Imeni》&#xff0c;前奏感觉很好熟悉&#xff0c;继续听&#xff0c;有种似曾相识的感觉&#xff0c;曲风和演唱风格都很熟悉&#xff0c;我极力的回忆&#xff0c;依稀想起水木年华有一首《莫斯科的黄昏》的演唱风格是在…

UOS简单评测

一位网友安装了UOS系统&#xff0c;并录制了视频&#xff0c;这位网友告知&#xff0c;UOS使用中无卡顿&#xff0c;比较流畅。以下为机器的硬件配置。就操作系统最关键的软件生态而言&#xff0c;UOS自带40多款原创应用和一个有2000多款优质应用的商店&#xff0c;包括微信、Q…

python使用opencv查找轮廓_Python+opencv学习记录20:轮廓发现,Pythonopencv

1.轮廓发现轮廓发现是基于图像边缘提取的基础寻找对象轮廓的方法&#xff0c;所以边缘提取的阈值选定会影响最终轮廓发现结果。1.1发现轮廓在此步骤中我们会使用到findContours这个API&#xff0c;其原型为&#xff1a;cv2.findContours(image, mode, method[, contours[, hier…

今天,送你一份交通行业最全数据集(共享单车、自动驾驶、网约出租车、交通信号识别)

近几年来共享单车、自动驾驶等交通行业发展得如荼如火&#xff0c;小编也一直有意识地收集相关数据集&#xff0c;经过长时间的积累和沉淀&#xff0c;已经拥有将近300G的交通数据&#xff0c;内容涵盖国内外“自动驾驶”、“共享单车”、“网约出租车”、“交通信号识别”等方…

空谈Saas都扯淡,让你看看真正的云计算

最近“虚拟化”的话题似乎热度有所降低&#xff0c;而“云计算”的概念却不断升温&#xff0c;就连Vmware的新的服务器虚拟化产品&#xff0c;都要加上一个第一款“云计算”操作系统&#xff0c;而正如hubisheng兄弟在《名头不小&#xff01;&#xff01;VMware vSphere实为VI升…

重要的是改变命运,而非升职加薪

阅读本文大概需要4分钟。写公众号以来&#xff0c;被问的最多的问题就是工作选择。在这件事上&#xff0c;很多读者明显会更重视薪资、福利、Title&#xff0c;而不是&#xff1a;未来会怎么样。就在昨天&#xff0c;又有一个读者问我Offer选择的问题&#xff0c;给出建议后&am…

python中的成员运算符是干嘛的_在Python中使用成员运算符的示例

下表列出了所有Python语言支持的成员运算符。例如&#xff1a;试试下面的例子就明白了所有的Python编程语言提供会员运算符&#xff1a;#!/usr/bin/pythona 10b 20list [1, 2, 3, 4, 5 ];if ( a in list ):print "Line 1 - a is available in the given list"else…

前方高能 | 你写过什么有趣的程序?最后一个笑出猪叫

苍冥 说&#xff1a;我们从高一到高三都强制采用图形计算器&#xff0c;可以画函数图像的那种。我们用的是德州仪器系列&#xff0c;Ti-Nspire&#xff0c;贵的要死要死的。然而我却买错了计算器的制式&#xff0c;便宜货&#xff0c;相比其他同学的系统少了很多重要的功能。作…

鼠标 . 软驱 . 打印机 . 硬盘. 风扇 . 常见事故处理 -

鼠标 . 软驱 . 打印机 . 硬盘. 风扇 . 常见事故处理 -鼠标鼠标的故障分析与维修比较简单&#xff0c;大部分故障为接口或按键接触不良、断线、机械定位系统污垢等原因造成的。少数故障为鼠标内部元器件或电路虚焊造成的&#xff0c;这主要存在于某些劣质产品中&#xff0c;其中…

php mysql 云虚拟机_虚拟机+apache+php+mysql 环境安装配置

虚拟机的安装&#xff1a;直接下一步即可&#xff0c;注意修改路径。安装完成后新建虚拟机&#xff0c;直接下一步。如果选择镜像文件后出现错误&#xff0c;可以试着去修改电脑bios中的虚拟化设置&#xff0c;改为enable&#xff0c;如下图&#xff1a;apache安装&#xff1a;…

python逐行读取数据时出现错误_python如何逐行读取数据

在实际开发的过程中&#xff0c;文件读写也很重要&#xff0c;下面说一下python如何逐行读取文件。如果程序要读取行&#xff0c;通常只能用文本方式来读取&#xff0c;道理很简单&#xff0c;只有文本文件才有行的概念&#xff0c;二进制文件没有所谓行的概念。文件对象提供了…

日志框架NLog之将日志发送到邮件

背景NLog可以将日志输出到不同的媒介上&#xff0c;邮件是其中一个&#xff0c;通过邮件可以让我们第一时间收到信息。使用SMTP协议通过电子邮件发送日志消息。与FallbackGroup Target很好地结合在一起&#xff0c;以创建具有多个SMTP主机的后备。配置语法<targets><t…

简单六步,用数据说服你的听众

“相比表格&#xff0c;利用数据图展现数据的方法有可观的优势。庞大的数据令人厌烦&#xff0c;普通人在其中根本获取不到有用的信息&#xff0c;就像从黄瓜里面汲取不到阳光一样。”——摘取自《Economic and Industrial Delusions》一书&#xff0c;作者Arthur Briggs Farqu…

CCNA第五章WAN连接

转载于:https://blog.51cto.com/centrevy/176434

探索 .NET Core 依赖注入的 IServiceCollection

如果您使用了.NET Core&#xff0c;则很可能已使用Microsoft.Extensions.DependencyInjection中的内置依赖项注入容器&#xff0c;在本文中&#xff0c;我想更深入地了解Microsoft Dependency Injection&#xff08;DI&#xff09;容器中的 IServiceCollection。什么是依赖注入…

dev可以运行mysql文件夹_Linux查看mysql 安装路径和运行路径

一、查看文件安装路径由于软件安装的地方不止一个地方&#xff0c;所有先说查看文件安装的所有路径(地址)。这里以mysql为例。比如说我安装了mysql,但是不知道文件都安装在哪些地方、放在哪些文件夹里&#xff0c;可以用下面的命令查看所有的文件路径在终端输入&#xff1a;whe…

看完这13张图,不得不佩服还是外国人会玩人工智能

对于程序员来说&#xff0c;机器学习领域无疑充满着巨大的诱惑和挑战&#xff0c;很多人对里面复杂的概念和算法头疼不已&#xff0c;那么&#xff0c;有没有一套对新手既友好又明了&#xff0c;对老手能加深印象&#xff0c;不断复习的学习办法呢&#xff1f;有&#xff0c;今…

python通过封装可以实现代码复用_Python学习笔记(五)函数和代码复用

函数能提高应用的模块性&#xff0c;和代码的重复利用率。在很多高级语言中&#xff0c;都可以使用函数实现多种功能。在之前的学习中&#xff0c;相信你已经知道Python提供了许多内建函数&#xff0c;比如print()。同样&#xff0c;你也可以自己创建函数&#xff0c;这被叫做用…

实用的网络命令汇总

通过ping检测网络故障的典型次序 正常情况下&#xff0c;当你使用ping命令来查找问题所在或检验网络运行情况时&#xff0c;你需要使用许多ping命令&#xff0c;如果所有都运行正确&#xff0c;你就可以相信基本的连通性和配置参数没有问题&#xff1b;如果某些ping命令出现运行…

EFCore查缺补漏(二):查询

相关文章&#xff1a; EFCore查缺补漏第 20 轮 TechEmpower 评测结果出炉了&#xff0c;ASP.NET Core 的 Plaintext 成绩名列前茅&#xff0c;带着 EFCore 的测试却在 Single query / Multiple queries / Fortunes 中落了下风&#xff0c;成绩远不如 dapper&#xff0c;更不如直…