Клиент не получает данные с сервера - PullRequest
0 голосов
/ 20 сентября 2019

Я пытаюсь создать приложение чата с графическим интерфейсом PyQt 4. Я решил "поместить" принимающую часть в другой поток, который начинается с приложения.
Проблема в том, что клиент не получает никакихданные с сервера.Я не знаю, что делать ... Это из-за нити?Прием находится в цикле while, поэтому он получает данные "24/7". Кажется, он должен работать.Что я делаю не так?
Мой код выглядит так:
server.py:

HEADER_LENGTH = 10

IP = "127.0.0.1"
PORT = 1234

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

server_socket.bind((IP, PORT))
server_socket.listen()

sockets_list = [server_socket]

clients = {}


def receive_message(client_socket):
    try:
        message_header = client_socket.recv(HEADER_LENGTH)

        if not len(message_header):
            return False

        message_length = int(message_header.decode("utf-8"))
        return {"header": message_header, "data": client_socket.recv(message_length)}
    except:
        return False


while True:
    read_sockets, _, exception_sockets = select.select(sockets_list, [], sockets_list)

    for notified_socket in read_sockets:
        if notified_socket == server_socket:
            client_socket, client_address = server_socket.accept()

            user = receive_message(client_socket)
            if user is False:
                continue

            sockets_list.append(client_socket)

            clients[client_socket] = user

            print(f"Accepted new connection from {client_address[0]}:{client_address[1]} username: {user['data'].decode('utf-8')}")

        else:
            message = receive_message(notified_socket)

            if message is False:
                print(f"Closed connection from {clients[notified_socket]['data'].decode('utf-8')}")
                sockets_list.remove(notified_socket)
                del clients[notified_socket]
                continue

            user = clients[notified_socket]

            print(f"Received message from {user['data'].decode('utf-8')}: {message['data'].decode('utf-8')}")

            for client_socket in clients:
                if client_socket != notified_socket:
                    client_socket.send(user['header'] + user['data'] + message['header'] + message['data'])

    for notified_socket in exception_sockets:
        sockets_list.remove(notified_socket)
        del clients[notified_socket]

client.py:

# -*- coding: utf-8 -*-

from PyQt4 import QtCore, QtGui
import socket
import select
import errno
import sys

HEADER_LENGTH = 10

IP = "127.0.0.1"
PORT = 1234

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((IP, PORT))
client_socket.setblocking(False)

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_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(800, 600)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
        MainWindow.setSizePolicy(sizePolicy)
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(_fromUtf8("logo.ico")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        MainWindow.setWindowIcon(icon)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.chatWindow = QtGui.QTextBrowser(self.centralwidget)
        self.chatWindow.setGeometry(QtCore.QRect(10, 10, 451, 501))
        self.chatWindow.setObjectName(_fromUtf8("chatWindow"))
        self.chatInput = QtGui.QTextEdit(self.centralwidget)
        self.chatInput.setGeometry(QtCore.QRect(10, 520, 351, 31))
        self.chatInput.setObjectName(_fromUtf8("chatInput"))
        self.sendButton = QtGui.QPushButton(self.centralwidget)
        self.sendButton.setGeometry(QtCore.QRect(370, 520, 91, 31))
        self.sendButton.setObjectName(_fromUtf8("sendButton"))
        self.usersWindow = QtGui.QTextBrowser(self.centralwidget)
        self.usersWindow.setGeometry(QtCore.QRect(470, 50, 321, 201))
        self.usersWindow.setObjectName(_fromUtf8("usersWindow"))
        self.usersLabel = QtGui.QLabel(self.centralwidget)
        self.usersLabel.setGeometry(QtCore.QRect(560, 10, 171, 31))
        self.usersLabel.setStyleSheet(_fromUtf8("font: 20pt \"MS Shell Dlg 2\";"))
        self.usersLabel.setObjectName(_fromUtf8("usersLabel"))
        MainWindow.setCentralWidget(self.centralwidget)
        self.usernameSelect = QtGui.QTextEdit(self.centralwidget)
        self.usernameSelect.setGeometry(QtCore.QRect(470, 270, 321, 31))
        self.usernameSelect.setStyleSheet(_fromUtf8("font: 12pt \"MS Shell Dlg 2\";"))
        self.usernameSelect.setObjectName(_fromUtf8("textEdit"))
        self.usernameSetButton = QtGui.QPushButton(self.centralwidget)
        self.usernameSetButton.setGeometry(QtCore.QRect(580, 310, 111, 41))
        self.usernameSetButton.setStyleSheet(_fromUtf8("font: 12pt \"MS Shell Dlg 2\";"))
        self.usernameSetButton.setObjectName(_fromUtf8("pushButton"))
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        self.menuFile = QtGui.QMenu(self.menubar)
        self.menuFile.setObjectName(_fromUtf8("menuFile"))
        self.menuEdit = QtGui.QMenu(self.menubar)
        self.menuEdit.setObjectName(_fromUtf8("menuEdit"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)
        self.actionClose = QtGui.QAction(MainWindow)
        self.actionClose.setObjectName(_fromUtf8("actionClose"))
        # self.actionChangeUsername = QtGui.QAction(MainWindow)
        # self.actionChangeUsername.setObjectName(_fromUtf8("actionChangeUsername"))
        self.menuFile.addAction(self.actionClose)
        # self.menuEdit.addAction(self.actionChangeUsername)
        self.menubar.addAction(self.menuFile.menuAction())
        self.menubar.addAction(self.menuEdit.menuAction())

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        self.sendButton.clicked.connect(self.send_message)
        self.actionClose.triggered.connect(self.close_application)
        self.usernameSetButton.clicked.connect(self.set_username)

        self.start_thread()

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "Pocket Chat", None))
        self.sendButton.setText(_translate("MainWindow", "Send", None))
        self.usersLabel.setText(_translate("MainWindow", "Active users", None))
        self.usernameSelect.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:\'MS Shell Dlg 2\'; font-size:12pt; font-weight:400; font-style:normal;\">\n"
        "<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>",
        None))
        self.usernameSetButton.setText(_translate("MainWindow", "Set username", None))
        self.menuFile.setTitle(_translate("MainWindow", "File", None))
        self.menuEdit.setTitle(_translate("MainWindow", "Edit", None))
        self.actionClose.setText(_translate("MainWindow", "Close", None))

    def send_message(self):
        message = self.chatInput.toPlainText()
        # print(message)
        if message:
            message = message.encode('utf-8')
            message_header = f"{len(message):<{HEADER_LENGTH}}".encode('utf-8')
            client_socket.send(message_header + message)

    def set_username(self):
        my_username = self.usernameSelect.toPlainText()

        username = my_username.encode('utf-8')
        username_header = f"{len(username):<{HEADER_LENGTH}}".encode('utf-8')
        client_socket.send(username_header + username)

        self.usernameSelect.deleteLater()
        self.usernameSetButton.deleteLater()

    def close_application(self):
        sys.exit(0)

    def start_thread(self):
        self.thread = ReceiveThread()
        self.thread.data_received.connect(self.on_receive_data)
        self.thread.start()

    def on_receive_data(self, username, message):
        if self.chatWindow.toPlainText() != "":
            current_chat = self.chatWindow.toPlainText()
            print('heloo')
            self.chatWindow.setText((current_chat + "\n" + f"{username}: {message}"))
        else:
            self.chatWindow.setText(f"{username}: {message}")


class ReceiveThread(QtCore.QThread):
    data_received = QtCore.pyqtSignal(object)

    def run(self):
        while True:
            try:
                while True:
                    # receive things
                    username_header = client_socket.recv(HEADER_LENGTH)
                    if not len(username_header):
                        print("Connection closed by the server.")
                        sys.exit()

                    username_length = int(username_header.decode('utf-8'))
                    username = client_socket.recv(username_length).decode('utf-8')

                    message_header = client_socket.recv(HEADER_LENGTH)
                    message_length = int(message_header.decode('utf-8'))
                    message = client_socket.recv(message_length).decode('utf-8')

                    print(f"{username}: {message}")  # Not working because It's not receiving data

                    # self.data_received.emit(str(username), str(message))  # Same here not working

            except IOError as e:
                if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK:
                    print("Reading error", str(e))
                    sys.exit()
                continue

            except Exception as e:
                print("General error", str(e))
                sys.exit()


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Я также должен сказать, что он основан на руководствах Sentdex на YouTube и, ну, он работает, но без графического интерфейса - на основе консоли.Я действительно понятия не имею, что происходит.Я отладил его, и он даже не достигает части username_header = client_socket.recv(HEADER_LENGTH) в классе ReceiveThread(QtCore.QThread) ... Цикл работает, но ничего в цикле не происходит.

...