简体   繁体   中英

Client threads in python socket server

I made a console chat app on Python socket. I want to implement threads on the client side so that there is one thread for receiving messages and one threads for sending messages. I am not really sure how to implement threads in python. Can someone please help or give me some suggestions.

Here's my code on the client side:

import socket
import select
import errno
import sys, struct
import pickle

HEADER_LENGTH = 1024
IP = "127.0.0.1"
PORT = 9669
def pad(package):
    return package + [0]*(HEADER_LENGTH-len(package))

def send_login_request(username):
    type_pac = 1
    package_type = type_pac.to_bytes(1,'big')
    print(package_type)
    length = len(username)
    if length > 1019:
        print ("Error: Username too long")
        sys.exit()
    package = package_type + struct.pack("I", length) + username.encode()
    # package = pad(package)
    
    return package

def send_message(recv_id, message):
    type_pac = 2
    package_type = type_pac.to_bytes(1,"big")
    recv_id = recv_id.to_bytes(1,'big')
    length = len(message)
    if length > 1015:
        print('message too long')
        sys.exit()
    package = package_type + recv_id + struct.pack('I', length) + message.encode()
   
    return package



client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect to a given ip and port
client_socket.connect((IP, PORT))

my_username = input("Username: ")
request = send_login_request(my_username)   
print(request)
client_socket.send(request)
username_conf = client_socket.recv(1024).decode()
print(username_conf)
if username_conf == "Welcome to the server":


    recv_id = int(input("Please enter receiver's id"))

    while True:
            # Wait for user to input a message

            message = input(f'{my_username} > ')
            # If message is not empty - send it
            if message:

                send_message = send_message(recv_id,message)
                client_socket.send(send_message)

            try:

                    message_receiver = client_socket.recv(HEADER_LENGTH).decode()
                    
                    # Print message
                    print(f'> {message_receiver}')

            except IOError as e:

                if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK:
                    print('Reading error: {}'.format(str(e)))
                    sys.exit()

                # We just did not receive anything
                continue

            except Exception as e:
                # Any other exception - something happened, exit
                print('Reading error: {}'.format(str(e)))
                sys.exit()

Thank you!

Have a look at this part of code:

while True:
    #[...]
    try:
        message_receiver = client_socket.recv(HEADER_LENGTH).decode()
        # Print message
        print(f'> {message_receiver}')
    except:
        #[...]

You need to make function for this try-except block and call it in a thread.

from threading import Thread
def recv():
    try:
        message_receiver = client_socket.recv(HEADER_LENGTH).decode()
        # Print message
        print(f'> {message_receiver}')
    except:
        #[...]


while True:
    #[...]
    recv_thread = Thread(target=recv)
    recv_thread.start()

And so your final code should look something like this:

import socket
import select
import errno
import sys, struct
import pickle

HEADER_LENGTH = 1024
IP = "127.0.0.1"
PORT = 9669
def pad(package):
    return package + [0]*(HEADER_LENGTH-len(package))

def send_login_request(username):
    type_pac = 1
    package_type = type_pac.to_bytes(1,'big')
    print(package_type)
    length = len(username)
    if length > 1019:
        print ("Error: Username too long")
        sys.exit()
    package = package_type + struct.pack("I", length) + username.encode()
    # package = pad(package)
    
    return package

def recv():
    try:
        message_receiver = client_socket.recv(HEADER_LENGTH).decode()
        # Print message
        print(f'> {message_receiver}')

    except:
        if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK:
            print('Reading error: {}'.format(str(e)))
            sys.exit()

        # We just did not receive anything
        continue

        except Exception as e:
            # Any other exception - something happened, exit
            print('Reading error: {}'.format(str(e)))
            sys.exit()

def send_message(recv_id, message):
    type_pac = 2
    package_type = type_pac.to_bytes(1,"big")
    recv_id = recv_id.to_bytes(1,'big')
    length = len(message)
    if length > 1015:
        print('message too long')
        sys.exit()
    package = package_type + recv_id + struct.pack('I', length) + message.encode()
   
    return package



client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect to a given ip and port
client_socket.connect((IP, PORT))

my_username = input("Username: ")
request = send_login_request(my_username)   
print(request)
client_socket.send(request)
username_conf = client_socket.recv(1024).decode()
print(username_conf)
if username_conf == "Welcome to the server":


    recv_id = int(input("Please enter receiver's id"))

    while True:
        # Wait for user to input a message

        message = input(f'{my_username} > ')
        # If message is not empty - send it
        if message:

            send_message = send_message(recv_id,message)
            client_socket.send(send_message)
            recv_thread = Thread(target=recv)
            recv_thread.start()            

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM