python - 使用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]")
解决方案
推荐阅读
- c++ - 使用 memory_order_relaxed 如何在典型架构上保证原子变量的修改总顺序?
- r - 可以在 R 中的地图上覆盖线图吗?
- java - 重启 Spring Boot 应用程序
- javascript - 用 Javascript 创建数组,带键
- c# - DataTable to XML File 存储在内存中并允许用户下载 XML
- arrays - hive - 是否可以从 Map 创建列
- android - 动态功能模块中 Fragments 的 fragmentScenario Espresso 测试
- java - 递归:扫描数字中数字的频率:redux
- angular - 如何在数据源数组中的数据更改后让 Angular mat-table 自动刷新
- python - 要求失败:未向此摘要器添加任何内容