首页 > 解决方案 > 使用python从线程向客户端发送消息

问题描述

此代码的目标是处理多个客户端,其中每个客户端都可以启动和停止计时器。\

当客户端运行“start”命令时,它会启动一个计时器。当它运行“停止”时,相同的计时器停止。每一秒,计时器的值都会在服务器中打印出来,但是最好将此值返回给客户端。

因此,handle_client是一个简单的函数,它从客户端读取消息并传递给Message_Handler以启动计时器。Message_Handler内部定义了线程。

如何将计时器时间(每秒打印的值)发送给客户端?

服务器

import socket
import threading
from datetime import datetime
import time

HEADER = 64
PORT = 5050
SERVER = "127.0.0.1" #socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "exit"
CONFIRM_MESSAGE = ("Message Received.").encode(FORMAT)

class Timer(object):

    def __init__(self):
        self._running = True

    def terminate(self):
        self._running = False
        delta_time = datetime.now() - self.start_time
        print("Chronometer Stop Time: ", delta_time)

    def run(self, conn):
        self.start_time = datetime.now()
        while self._running:
            time.sleep(1)
            if self._running:
                delta_time = datetime.now() - self.start_time
                conn.send(str(delta_time).encode(FORMAT))
                print("Chronometer: ", delta_time)


class MessageHandler(object):

    def read_message(self, conn, addr, msg):
        print(f"Address {addr}: Message: {msg}")

        if (msg == "start"):
            conn.send(("[STARTING TIMER]").encode(FORMAT))
            self.timer = Timer()
            self.thread = threading.Thread(target=self.timer.run, args=(conn,))
            self.thread.start()

        elif(msg == "stop"):
            self.timer.terminate()
            return CONFIRM_MESSAGE

        else:
            return CONFIRM_MESSAGE

def handle_client(conn, addr):
    print(f"\n[NEW CONNECTION] {addr} connected.")
    mh = MessageHandler()

    connected = True
    while connected:
        msg_length = conn.recv(HEADER).decode(FORMAT)
        if msg_length:
            msg_length = int(msg_length)
            msg = conn.recv(msg_length).decode(FORMAT)
            if msg == DISCONNECT_MESSAGE:
                connected = False
            return_msg = mh.read_message(conn, addr, msg)
            if(return_msg != None):
                conn.send(return_msg)

    conn.close()


if __name__ == "__main__":
    server = socket.socket(family = socket.AF_INET, type = socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server.bind(ADDR)
    print("[STARTING] server is starting...")
    server.listen()  # We can use an argument that is an int and limitates the number of connections
    print(f"[LISTNING] Server is listening on {SERVER}")

    while True:
        conn, addr = server.accept()
        thread = threading.Thread(target=handle_client, args=(conn, addr))
        thread.start()

客户端

import socket

HEADER = 64
PORT = 5050
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "exit"
SERVER = "192.168.1.251"
SERVER = "127.0.0.1"
ADDR = (SERVER, PORT)

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)

def send(msg):
    message = msg.encode(FORMAT)
    msg_length = len(message)
    send_length = str(msg_length).encode(FORMAT)
    send_length += b' ' * (HEADER - len(send_length))
    client.send(send_length)
    client.send(message)
    print(client.recv(2048).decode(FORMAT))

connect = True
while connect == True:
    input_msg = input("message: ")
    send(input_msg)
    if(input_msg == DISCONNECT_MESSAGE):
        send(DISCONNECT_MESSAGE)
        connect = False
    data = client.recv(64)
    print(data)
print("[SYSTEM DISCONNECTED]")

标签: pythonmultithreadingsockets

解决方案


推荐阅读