召尸墓响,樱川doh美,濠江岁月在线观看
本文在上文的基础上重新实现支持多线程的服务器。
以下为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<<date 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服务器实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持移动技术网。
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Python 实现将numpy中的nan和inf,nan替换成对应的均值
python爬虫把url链接编码成gbk2312格式过程解析
网友评论