def createConnection(self, localIP, localPort): localaddr = QHostAddress() localaddr.setAddress(localIP) self.setLocalIp(localIP) self.setLocalPort(localPort) isOK = self.udpSocket.bind(localaddr, localPort) return isOK
def __init__(self, host=None, port=None, type=None, parent=None): super(UDPClient, self).__init__(parent) mcast_addr = host mcast_port = port type = type self.statusLabel = QLabel("Listening for broadcasted messages") quitButton = QPushButton("&Quit") self.udpSocket = QUdpSocket(self) dstAddress = QHostAddress() dstAddress.setAddress(mcast_addr) self.udpSocket.bind(dstAddress, mcast_port) self.udpSocket.readyRead.connect(self.processPendingDatagrams) quitButton.clicked.connect(self.close) buttonLayout = QHBoxLayout() buttonLayout.addStretch(1) buttonLayout.addWidget(quitButton) buttonLayout.addStretch(1) mainLayout = QVBoxLayout() mainLayout.addWidget(self.statusLabel) mainLayout.addLayout(buttonLayout) self.setLayout(mainLayout) self.setWindowTitle("Broadcast Receiver")
def send(self, data, dstIp, dstPort): """ udp-发送 :param data: str or bytearray :param dstIp: :param dstPort: :return: """ dstAddress = QHostAddress() dstAddress.setAddress(dstIp) if isinstance(data, str): self.udpSocket.writeDatagram(data, dstAddress, dstPort) elif isinstance(data, bytearray) or isinstance(data, bytes): self.udpSocket.writeDatagram(QByteArray(data), dstAddress, dstPort) else: print('unexpected input type!')
def ipAddressFieldUpdated(self): hostAddress = QHostAddress() if hostAddress.setAddress(self.ipAddressField.text()): self.ipAddress = self.ipAddressField.text() else: self.ipAddress = None
class TcpClient(QWidget): def __init__(self): super().__init__() self.isOnline = False self.port = 8888 self.serverIP = QHostAddress('127.0.0.1') self.initUI() def initUI(self): self.ui = ui_tcpClient.Ui_Form() self.ui.setupUi(self) self.ui.sendBtn.setEnabled(False) self.ui.portLineEdit.setText(str(self.port)) self.ui.serverIPLineEdit.setText(self.serverIP.toString()) self.ui.enterBtn.clicked.connect(self.slotEnterOrLeave) self.ui.sendBtn.clicked.connect(self.slotSend) self.ui.sendLineEdit.returnPressed.connect(self.slotSend) self.show() def slotEnterOrLeave(self): if not self.isOnline: if not self.validate(): return self.enterRoom() else: self.leaveRoom() def validate(self): if self.ui.userNameLineEdit.text() == '': QMessageBox().information(self, 'ERROR', 'User Name Error!') return False self.userName = self.ui.userNameLineEdit.text() if not self.serverIP.setAddress( self.ui.serverIPLineEdit.text()): # 判断给定的IP是否能够被正确解析 QMessageBox().information(self, 'ERROR', 'Server IP Error!') return False if not (0 <= int(self.ui.portLineEdit.text()) <= 65535): QMessageBox().information(self, 'ERROR', 'Server Port Error!') return False self.port = int(self.ui.portLineEdit.text()) return True def enterRoom(self): self.tcpSocket = QTcpSocket(self) self.tcpSocket.connectToHost(self.serverIP, self.port) self.tcpSocket.connected.connect(self.slotConnected) self.tcpSocket.readyRead.connect(self.slotDataReceived) self.tcpSocket.disconnected.connect(self.slotDisconnected) self.tcpSocket.error.connect(self.slotErrorOccured) def leaveRoom(self): sendData = '[-] ' + self.userName + ': Leave Chat Room' self.tcpSocket.write(bytes(sendData, encoding='utf-8')) self.tcpSocket.disconnectFromHost() def slotSend(self): if self.ui.sendLineEdit.text() == '': return sendData = self.userName + ': ' + self.ui.sendLineEdit.text() self.tcpSocket.write(bytes(sendData, encoding='utf-8')) self.ui.sendLineEdit.clear() def slotConnected(self): self.ui.sendBtn.setEnabled(True) self.ui.userNameLineEdit.setEnabled(False) self.ui.serverIPLineEdit.setEnabled(False) self.ui.portLineEdit.setEnabled(False) self.ui.enterBtn.setText('Leave Chat Room') self.isOnline = True sendData = '[+] ' + self.userName + ': Enter Chat Room' self.tcpSocket.write(bytes(sendData, encoding='utf-8')) def slotDataReceived(self): recvData = '' while self.tcpSocket.bytesAvailable() > 0: recvData = self.tcpSocket.read(self.tcpSocket.bytesAvailable()) self.ui.contentListWidget.addItem(str(recvData, encoding='utf-8')) self.ui.contentListWidget.scrollToBottom() # 滚动到最后一行 def slotDisconnected(self): self.ui.sendBtn.setEnabled(False) self.ui.userNameLineEdit.setEnabled(True) self.ui.serverIPLineEdit.setEnabled(True) self.ui.portLineEdit.setEnabled(True) self.ui.enterBtn.setText('Enter Chat Room') self.isOnline = False def closeEvent(self, event): if self.isOnline: msg = 'Are you sure to leave the chat room ?' reply = QMessageBox().warning(self, 'Quit', msg, QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: self.leaveRoom() event.accept() else: event.ignore() else: event.accept() def slotErrorOccured(self, socketError): if socketError == 0: msg = '[*] ConnectionRefusedError: The connection was refused by the peer (or timed out).' self.ui.contentListWidget.addItem(msg) elif socketError == 1: msg = '[*] RemoteHostClosedError: The remote host closed the connection.' self.ui.contentListWidget.addItem(msg)
class TcpServer(QWidget): def __init__(self): super().__init__() self.isUp = False self.port = 8888 self.serverIP = QHostAddress('127.0.0.1') self.tcpClientList = [] self.initUi() def initUi(self): self.ui = ui_tcpServer.Ui_Form() self.ui.setupUi(self) self.ui.splitter.setStretchFactor(1,1) self.ui.portLineEdit.setText(str(self.port)) self.ui.serverIPLineEdit.setText(self.serverIP.toString()) self.ui.openBtn.clicked.connect(self.slotOpenOrClose) self.show() def validate(self): if not self.serverIP.setAddress(self.ui.serverIPLineEdit.text()): # 判断给定的IP是否能够被正确解析 QMessageBox().information(self, 'ERROR', 'Server IP Error!') return False if not (0 <= int(self.ui.portLineEdit.text()) <= 65535): QMessageBox().information(self, 'ERROR', 'Server Port Error!') return False self.port = int(self.ui.portLineEdit.text()) return True def slotOpenOrClose(self): if not self.isUp: if not self.validate(): return self.openRoom() else: self.closeRoom() def openRoom(self): self.ui.openBtn.setText('Close Chat Room') self.isUp = True self.ui.serverIPLineEdit.setEnabled(False) self.ui.portLineEdit.setEnabled(False) self.tcpServer = QTcpServer() self.tcpServer.listen(self.serverIP, self.port) msg = '[*] Server is listening on {}:{} ........'.format(self.serverIP.toString(), self.port) self.ui.contentListWidget.addItem(msg) self.tcpServer.newConnection.connect(self.addClient2List) def closeRoom(self): del (self.tcpServer) self.tcpClientList = [] self.ui.userListWidget.clear() self.isUp = False self.ui.serverIPLineEdit.setEnabled(True) self.ui.portLineEdit.setEnabled(True) self.ui.openBtn.setText('Open Chat Room') msg = '[*] Chat Room is closed........' self.ui.contentListWidget.addItem(msg) def addClient2List(self): tcpClientSocket = self.tcpServer.nextPendingConnection() client = ConnectClient(tcpClientSocket) self.tcpClientList.append(client) tcpClientSocket.readyRead.connect(self.slotDataReceived) tcpClientSocket.disconnected.connect(self.slotDisconnected) self.ui.onlineNumLabel.setText(str(len(self.tcpClientList))) def slotDataReceived(self): tcpClientSocket = self.sender() recvData = '' while tcpClientSocket.bytesAvailable() > 0: recvData += str(tcpClientSocket.read(tcpClientSocket.bytesAvailable()), encoding='utf-8') self.ui.contentListWidget.addItem(recvData) self.ui.contentListWidget.scrollToBottom() self._parseData(recvData, tcpClientSocket) # 实现信息的广播, tcpClientList中保存了所有与服务器相连的TcpClientSocket对象 for client in self.tcpClientList: client.socket.write(bytes(recvData, encoding='utf-8')) def slotDisconnected(self): # 从tcpClientList列表中将断开连接的TcpClientSocket对象删除 tcpClientSocket = self.sender() idx = self._findClient(tcpClientSocket) if idx >= 0: del (self.tcpClientList[idx]) self.ui.onlineNumLabel.setText(str(len(self.tcpClientList))) def _findClient(self, socket): for idx, client in enumerate(self.tcpClientList): if client.socket is socket: return idx return -1 def _parseData(self, data, socket): if data.startswith('[+]'): name = data.split(':')[0][4:] idx = self._findClient(socket) if idx >= 0: self.tcpClientList[idx].name = name self.ui.userListWidget.addItem(name) elif data.startswith('[-]'): idx = self._findClient(socket) if idx >= 0: self.ui.userListWidget.takeItem(idx) def closeEvent(self, event): if self.isUp: msg = 'Are you sure to close the chat room ?' reply = QMessageBox().warning(self, 'Quit', msg, QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: self.closeRoom() event.accept() else: event.ignore() else: event.accept()
class UiDialog(QDialog): port_udp = 1345 def __init__(self, dialog, parent=None): dialog.setObjectName("udp-test") dialog.resize(480, 400) super(UiDialog, self).__init__(parent) self.pushButton_2 = QtWidgets.QPushButton(dialog) self.pushButton = QtWidgets.QPushButton(dialog) self.textEdit = QtWidgets.QTextEdit(dialog) self.textEdit_port = QtWidgets.QTextEdit(dialog) self.textEdit_url = QtWidgets.QTextEdit(dialog) self.textBrowser = QtWidgets.QTextBrowser(dialog) self.udpSocket_sed = QUdpSocket() self.udpSocket_rev = QUdpSocket() # self.udpSocket_rev.bind(self.port_udp) self.udpSocket_rev.readyRead.connect(self.upd_rev) self.url = QHostAddress() self.url.setAddress("127.0.0.1") self.ret_ui(dialog) QtCore.QMetaObject.connectSlotsByName(dialog) def setup_ui(self): self.textBrowser.setGeometry(QtCore.QRect(40, 50, 301, 221)) self.textBrowser.setObjectName("textBrowser") self.textEdit.setGeometry(QtCore.QRect(40, 290, 301, 74)) self.textEdit.setObjectName("textEdit") self.textEdit_port.setGeometry(QtCore.QRect(360, 150, 120, 20)) self.textEdit_port.setObjectName("textEdit_port") self.textEdit_url.setGeometry(QtCore.QRect(360, 200, 120, 20)) self.textEdit_url.setObjectName("textEdit_url") self.pushButton.setGeometry(QtCore.QRect(360, 50, 120, 32)) self.pushButton.setObjectName("pushButton") self.pushButton.clicked.connect(self.upd_sed) self.pushButton_2.setGeometry(QtCore.QRect(360, 100, 120, 32)) self.pushButton_2.setObjectName("pushButton_2") self.pushButton_2.clicked.connect(self.port_ui) def ret_ui(self, dialog): _translate = QtCore.QCoreApplication.translate dialog.setWindowTitle(_translate("udp-test", "udp网络测试工具")) self.pushButton.setText(_translate("udp-test", "发送")) self.pushButton_2.setText(_translate("udp-test", "确认端口及地址")) self.textEdit_port.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" "p, li { white-space: pre-wrap; }\n" "</style></head><body style=\" font-family:\'.SF NS Text\'; font-size:13pt; font-weight:400; font-style:normal;\">\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">1345</p></body></html>")) self.textEdit_url.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" "p, li { white-space: pre-wrap; }\n" "</style></head><body style=\" font-family:\'.SF NS Text\'; font-size:13pt; font-weight:400; font-style:normal;\">\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">127.0.0.1</p></body></html>")) def port_ui(self): self.port_udp = int(self.textEdit_port.toPlainText()) self.url.setAddress(str(self.textEdit_url.toPlainText())) self.udpSocket_rev.bind(self.port_udp) def upd_rev(self): while self.udpSocket_rev.hasPendingDatagrams(): datagram, host, port = self.udpSocket_rev.readDatagram(self.udpSocket_rev.pendingDatagramSize()) try: # Python v3. datagram = str(datagram, encoding='utf-8') except TypeError: # Python v2. pass self.textBrowser.insertPlainText("发自 {}:{} 到 localhost:{}:\n".format(host.toIPv6Address()[-4:], port, str(self.port_udp)) + datagram + '\n') def upd_sed(self): datagram = str(self.textEdit.toPlainText()) self.udpSocket_sed.writeDatagram(datagram.encode("utf-8"), self.url, self.port_udp)