python套接字服务器中的客户端线程

python套接字服务器中的客户端线程,python,multithreading,sockets,tcp,Python,Multithreading,Sockets,Tcp,我在Python套接字上制作了一个控制台聊天应用程序。我想在客户端实现线程,这样就有一个用于接收消息的线程和一个用于发送消息的线程。我不确定如何在python中实现线程。有人能帮我一下或给我一些建议吗 以下是我在客户端的代码: import socket import select import errno import sys, struct import pickle HEADER_LENGTH = 1024 IP = "127.0.0.1" PORT = 9669 d

我在Python套接字上制作了一个控制台聊天应用程序。我想在客户端实现线程,这样就有一个用于接收消息的线程和一个用于发送消息的线程。我不确定如何在python中实现线程。有人能帮我一下或给我一些建议吗

以下是我在客户端的代码:

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()

谢谢大家!

看看这部分代码:

为True时:
#[...]
尝试:
message_receiver=client_socket.recv(HEADER_LENGTH).decode()
#打印消息
打印(f'>{message_receiver}')
除:
#[...]
您需要为此
创建函数try except
块并在线程中调用它

从线程导入线程
def recv():
尝试:
message_receiver=client_socket.recv(HEADER_LENGTH).decode()
#打印消息
打印(f'>{message_receiver}')
除:
#[...]
尽管如此:
#[...]
recv_线程=线程(目标=recv)
recv_thread.start()
最后的代码应该是这样的:

导入套接字
导入选择
输入错误号
导入系统,结构
进口泡菜
标题长度=1024
IP=“127.0.0.1”
端口=9669
def垫(包装):
返回文件包+[0]*(标题长度(文件包))
def发送登录请求(用户名):
类型_pac=1
包类型=类型包到字节(1,'big')
打印(包装类型)
长度=长度(用户名)
如果长度>1019:
打印(“错误:用户名太长”)
sys.exit()
package=package_type+struct.pack(“I”,长度)+username.encode()
#包装=垫(包装)
退货包装
def recv():
尝试:
message_receiver=client_socket.recv(HEADER_LENGTH).decode()
#打印消息
打印(f'>{message_receiver}')
除:
如果e.errno!=errno.EAGAIN和e.errno!=errno.EWOLDBLOCK:
打印('读取错误:{}'。格式(str(e)))
sys.exit()
#我们只是没有收到任何东西
持续
例外情况除外,如e:
#任何其他异常-发生了什么,退出
打印('读取错误:{}'。格式(str(e)))
sys.exit()
def发送消息(接收id,消息):
类型_pac=2
包类型=类型包到字节(1,“大”)
recv_id=recv_id.to_字节(1,'big')
长度=长度(信息)
如果长度>1015:
打印('消息太长')
sys.exit()
package=package\u type+recv\u id+struct.pack('I',length)+message.encode()
退货包装
client\u socket=socket.socket(socket.AF\u INET,socket.SOCK\u流)
#连接到给定的ip和端口
客户端_套接字连接((IP,端口))
我的用户名=输入(“用户名:”)
请求=发送登录请求(我的用户名)
打印(请求)
客户端\u套接字发送(请求)
username\u conf=client\u socket.recv(1024).decode()
打印(用户名\配置)
如果username_conf==“欢迎使用服务器”:
recv_id=int(输入(“请输入接收方id”))
尽管如此:
#等待用户输入消息
message=输入(f'{my_username}>')
#如果消息不是空的-发送它
如果消息:
发送消息=发送消息(接收id,消息)
客户端\u套接字.send(发送\u消息)
recv_线程=线程(目标=recv)
recv_thread.start()