закрытие qthread - PullRequest
       19

закрытие qthread

0 голосов
/ 25 февраля 2020

Я написал проект с пользовательским интерфейсом в pyqt и серверным потоком (который открывает новый поток для каждого нового клиента, который подключается). Клиенты отправляют сообщения на сервер, а сервер печатает эти сообщения в интерфейсе пользователя. После 1 сообщения, полученного сервером (которое печатает пользовательский интерфейс), сервер перестает работать и прекращает получать новые сообщения.

Поступающие потоки:

class Client_Recieve_Msg(QtCore.QThread):

    def __init__(self, my_ip, RECEIVE_PORT, private_key):
        QtCore.QThread.__init__(self)
        self.my_ip = my_ip
        self.RECEIVE_PORT = RECEIVE_PORT
        self.private_key = private_key

    def __del__(self):
        self.run()

    def run(self):
        """
        In order to receive massages from other clients the client opens a server.
        The function needs the client's ip and the client's private key.
        """
        try:
            ADDR = (self.my_ip, self.RECEIVE_PORT)
            BUFSIZ = 2048
            serversock = socket(AF_INET, SOCK_STREAM)
            serversock.bind(ADDR)
            serversock.listen(2)
            while True:
                clientsock, addr = serversock.accept()
                print "here"
                send_a_msg = server_side_handler(clientsock, addr, BUFSIZ, self.private_key)
                send_a_msg.start()
        except:
            i = 1

class server_side_handler (QtCore.QThread):

    def __init__(self, clientsock, addr, BUFSIZ, private_key):
        QtCore.QThread.__init__(self)
        self.clientsock = clientsock
        self.addr = addr
        self.BUFSIZ = BUFSIZ
        self.private_key = private_key

    def __del__(self):
        self.run()

    def run(self):
        """
        Every node that connects to the server side of the client starts a thread of this function,
        the function receives the msg and prints it at the user's ui.
        The server's port is 50001.
        The function requires all the connection info and the clients private key.
        """
        msg = ""
        data = self.clientsock.recv(self.BUFSIZ)
        self.clientsock.send("ack")
        while data != "end":
            msg += data
            data = self.clientsock.recv(self.BUFSIZ)
            self.clientsock.send("ack")
        data = msg
        self.clientsock.close()

        # The received data is saparated to 2 parts the encrypted symmetric key and the encrypted msg
        # and between those 2 parts there is a separator that indicates where is the end of the first
        # part and the start of the second part.
        SEPARATOR = "$#$"

        # Unserializing the data
        data = pickle.loads(data)

        # This part is unalizing the received data and decrypting the msg.
        sym_key_loc = data.index(SEPARATOR)
        sym_key_str = data[:sym_key_loc]
        dec_sym_key = decrypt_a_msg(sym_key_str, self.private_key)
        f = Fernet(dec_sym_key)
        dec_msg = f.decrypt(data[sym_key_loc+2:])
        print "got the msg"
        Ui_Form.msg_to_display = dec_msg

Код пользовательского интерфейса:

from PyQt4 import QtCore, QtGui
import sys


try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)



class Ui_Form(object):
    new_msg_to_send = ""
    UI = ""
    msg_to_display = ""
    def setupUi(self, Form):
        Form.setObjectName(_fromUtf8("Form"))
        Form.setWindowModality(QtCore.Qt.NonModal)
        Form.resize(425, 300)
        Form.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.text_msgs = QtGui.QTextEdit(Form)
        self.text_msgs.setGeometry(QtCore.QRect(0, 0, 431, 231))
        font = QtGui.QFont()
        font.setFamily(_fromUtf8("Microsoft JhengHei"))
        font.setPointSize(10)
        self.text_msgs.setFont(font)
        self.text_msgs.setReadOnly(True)
        self.text_msgs.setObjectName(_fromUtf8("text_msgs"))
        self.lineEdit = QtGui.QLineEdit(Form)
        self.lineEdit.setGeometry(QtCore.QRect(0, 230, 311, 71))
        self.lineEdit.setText(_fromUtf8(""))
        self.lineEdit.setFrame(True)
        self.lineEdit.setEchoMode(QtGui.QLineEdit.Normal)
        self.lineEdit.setCursorMoveStyle(QtCore.Qt.LogicalMoveStyle)
        self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
        self.pushButton = QtGui.QPushButton(Form)
        self.pushButton.setGeometry(QtCore.QRect(310, 230, 121, 71))
        self.pushButton.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        icon = QtGui.QIcon.fromTheme(_fromUtf8("send"))
        self.pushButton.setIcon(icon)
        self.pushButton.setAutoRepeat(False)
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.pushButton.clicked.connect(lambda:self.send_msg())
        self.retranslateUi(Form)
        QtCore.QTimer.singleShot(100, self.check_for_new_msg)
        QtCore.QMetaObject.connectSlotsByName(Form)


    def retranslateUi(self, Form):
        Form.setWindowTitle(_translate("Form", "Form", None))
        self.pushButton.setText(_translate("Form", "send", None))

    def handle_display_trigger(self):
        self.new_msg(self.display_a_msg)

    def send_msg(self):
        text = self.lineEdit.text()
        self.lineEdit.setText("")
        self.text_msgs.append("You: "+text)
        Ui_Form.new_msg_to_send = text

    def new_msg(self, msg):
        self.text_msgs.append("Other: "+msg)    

    def check_for_new_msg(self):
        if self.msg_to_display != "":
            self.new_msg(self.msg_to_display)
            self.msg_to_display = ""
        QtCore.QTimer.singleShot(100, self.check_for_new_msg)


def start_ui():
    app = QtGui.QApplication(sys.argv)
    Form = QtGui.QWidget()
    ui = Ui_Form()
    Ui_Form.UI = ui
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

основной:

# Getting the client's ip
    host_name = gethostname()    
    my_ip = gethostbyname(host_name)  

    # Generate the public key and the private key of this client.
    private_key = generate_a_keys()
    public_key = private_key.public_key()

    #RECEIVE_PORT = int(raw_input("please enter the client's port (only 50004+): "))
    RECEIVE_PORT = 50005

    recieve_a_msg = Client_Recieve_Msg(my_ip, RECEIVE_PORT, private_key)
    recieve_a_msg.start()
    start_ui()
...