Ошибка: «Недопустимый литерал для int () с основанием 10» - ошибка приложения чата, когда сервер передает два сообщения одновременно клиенту - PullRequest
0 голосов
/ 10 октября 2019

У меня есть чат-сервер, на котором работает несколько клиентов, и он прекрасно работает, когда одно сообщение отправляется одним клиентом, а затем другим клиентом вводит его в качестве входа для получения сообщения с сервера. Однако, когда один клиент отправляет два сообщения, а другой пытается их получить, я получаю неверную буквальную ошибку, из-за которой соединение закрывается. Я не знаю, что происходит, и я не понимаю, как это исправить. Пожалуйста помоги! Любые предложения приветствуются!

Сервер:

import socket
import select

host = '127.0.0.1'
port = 65432
HEADER_LENGTH = 100

def socket_setup():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # Creating socket object
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # Allowing the same address to be reused
    s.bind((host, port))  # Binding the socket to the IP address and port number
    s.listen()  # Listening for incoming connections
    print(f'Listening for incoming connections on IP address {host}.')
    return s

def client_data(s):
    client_socket_list = [s]  # List for appending connected sockets to for select to keep track of
    clients = {}  # Dict for informing other clients in a better way than just socket info who they are
    return client_socket_list, clients

def receiving_messages(client_socket):
     try:
        msg_header = client_socket.recv(HEADER_LENGTH)  # Getting the message header
        # If we do not get any data for the message header then we need code to handle this
        if not len(msg_header):
            return False
        else:
            msg_length = int(msg_header.decode("utf-8"))  # Converting the header to a length
             return {"header": msg_header, "data": client_socket.recv(msg_length)}  # Returning the data from the message
    except:
        return False

def client_accept(s):
    client_socket, client_address = s.accept()  # Accepting a new connection, getting unique client socket and address
    user = receiving_messages(client_socket)  # User data

    return client_socket, client_address, user

def info_update(client_socket, client_socket_list, clients, user, client_address):
    client_socket_list.append(client_socket)  # Adding the new client socket to the list
    clients[client_socket] = user  # Adding the user information to the clients dictionary
    print(f"New connection accepted from IP: {client_address[0]} Port: {client_address[1]} username: 
{user['data'].decode('utf-8')}")

    return clients

def broadcast(clients, x, user, message):  # Now sharing the message with all other users in the chatroom
    for client_socket in clients:  # Iterating over all connected clients
        if client_socket != x:  # Stopping the message being sent out to the client that sent the message
            client_socket.send(user['header'] + user['data'] + message['header'] + message['data'])  # Sending the message from client X to all other clients


def message_handling(client_socket_list, s, clients):
    while True:
        # Below socket is taking in parameters (1, 2, 3) (1) the read list(things we want to read in)(2) the sockets we want to write (3) sockets with possible error
        read_sockets, _, exception_sockets = select.select(client_socket_list, [], client_socket_list)

        for x in read_sockets:  # x = socket that has been notified of chat room entry (iterating over sockets with info to be read). Iterating over all sockets in the list.

            if x == s:  # Handling for a new connection
                client_socket, clients_address, user = client_accept(s)

                if user is False:  # Handling for a disconnection
                    continue

                info_update(client_socket, client_socket_list, clients, user, clients_address)

            else:

                message = receiving_messages(x)  # If the socket is not the server socket then we have a message to read

                if message is False:
                    print(f"Connection closed from {clients[x]['data'].decode('utf-8')}")
                    client_socket_list.remove(x)  # Removing the socket on which the connection has been closed from the list of clients
                    del clients[x]  # Removing the client info from the dict
                    continue

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

        # Removing users if there is a socket error causing unexpected connection closure
        for x in exception_sockets:
            client_socket_list.remove(x)
            del clients[x]

def main():
    s = socket_setup()
    client_socket_list, clients = client_data(s)
    message_handling(client_socket_list, s, clients)

if __name__ == "__main__":
    main()

Клиент:

import socket
import errno
import sys

HEADER_LENGTH = 100
host = '127.0.0.1'
port = 65432

def client_socket_setup():
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.connect((host, port))
    client_socket.setblocking(False)  # Telling the recv method not to block

    return client_socket

def username(client_socket):     # Server expects the first message to be a username input by the user
    my_username = input('Username: ')  # User input of username (Not encoded in utf-8 bytes)
    username = my_username.encode('utf-8')  # Encoding the user into bytes to send
    username_header = f'{len(username):<{HEADER_LENGTH}}'.encode('utf-8')  # Defining a variable username_header and stating that the length of the username must be aligned to the left within the specified length set by HEADER_LENGTH
    client_socket.send(username_header + username)  # Sending client username info to the server

    return my_username, username_header

def message_sending(message, HEADER_LENGTH, client_socket):
message = message.encode('utf-8')  # Encoding the message into utf-8 bytes ready to send to the 
server
    message_header = f'{len(message):<{HEADER_LENGTH}}'.encode('utf-8')  # Defining a variable message_header containing the information that the length of the message must be aligned to the left within the length of the username header
    client_socket.send(message_header + message)  # Encoded message now sent along with the message length info

def receiving_user(username_header, client_socket):  # Getting the username of the other client that sent the last message
    username_length = int(username_header.decode('utf-8'))
    username = client_socket.recv(username_length).decode('utf-8')

    return username

def receiving_message(client_socket):  # Getting the message from the server that the other client has sent
    message_header = client_socket.recv(HEADER_LENGTH)
    message_length = int(message_header.decode('utf-8').strip())
    username_length = message_length + 1  # Fix for the bug that was causing the invalid literal parsing error!
    message = client_socket.recv(username_length).decode('utf-8')

    return message

def send_and_recv(my_username, client_socket, HEADER_LENGTH):
    while True:
        message = input(f'{my_username} : ')  # my_username used so it is not already encoded when using it here to attach the message the user inputs

        # Sending messages and handling for an empty input i.e. no message input
        if message:
            message_sending(message, HEADER_LENGTH, client_socket)
        try:
            while True:
                # Receiving messages from other clients
                username_header = client_socket.recv(HEADER_LENGTH)

                if not len(username_header):  # Handling for an error where the username header length is not what it should be
                    print('connection closed by the server')
                    sys.exit()  # System closing the connection due to no more messages

                username = receiving_user(username_header, client_socket)
                message = receiving_message(client_socket)

                print(f'{username}: {message}')  # Printing the message from the other client along with that clients username

        # Preventing consistent errors being raised causing issue within the program as within a non-blocking connection an error will continually be raised when no messages are coming through etc
        except IOError as e:
            if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK:
                print('Expecting message but not receiving ', str(e))
                sys.exit()
            continue

        # Handling for all other unexpected errors that may occur
        except Exception as e:
            print('General error: ', str(e))
            sys.exit()

def main():
    client_socket = client_socket_setup()
    my_username, username_header = username(client_socket)
    send_and_recv(my_username, client_socket, HEADER_LENGTH)

if __name__ == "__main__":
    main()

Ошибка:

 File "C:/Users/hassallj/Documents/Python Scripts/Chat_Server_and_Client/Chat_App/Client.py", line 60, in send_and_recv username = receiving_user(username_header, client_socket) File "C:/Users/hassallj/Documents/Python Scripts/Chat_Server_and_Client/Chat_App/Client.py", line 31, in receiving_user username_length = int(username_header.decode('utf-8')) ValueError: invalid literal for int() with base 10: ' 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...