Python

多线程练习

2018-08-08  本文已影响88人  GHope

一个进程结束的前提为进程内所有线程结束。
结束子线程-->让子线程中的任务结束(就是让run方法结束:结束循环多用添加类属性设置标志作为判断条件)
如果一个线程崩溃,不对其它线程造成影响。

写一个服务器,可以和多个客户端同时通信,并且把接收的消息显示在屏幕上

主程序

import socket
import pygame
from homework.color import Color
from homework.myThread import AcceptThread
from homework.myThread import ConversationThread


def creat_server():
    """创建服务器"""
    server = socket.socket()
    server.bind(('10.7.181.56', 8088))
    server.listen(520)

    # 在一个子线程中去监听
    server_thread = AcceptThread(server)
    server_thread.start()


if __name__ == '__main__':
    # 创建服务器
    creat_server()

    # 准备显示信息的屏幕
    pygame.init()
    screen = pygame.display.set_mode((600, 400))
    screen.fill(Color.white)
    pygame.display.flip()

    # 让屏幕一直存在
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()

        # 获取每条信息,显示在屏幕上
        screen.fill(Color.white)
        for message in ConversationThread.all_message[:]:
            if message.alive:
                # 显示信息
                font = pygame.font.SysFont('Time', 30)
                text = font.render(message.text, True, message.color)
                screen.blit(text, (message.x, message.y))

                # 滚动弹幕
                message.move()
            else:
                ConversationThread.all_message.remove(message)

        pygame.display.update()

    print('退出!!!')

线程类

from threading import Thread
import socket
from random import randint
from homework.color import Color


class Message:
    """文字信息类"""

    def __init__(self, text):
        self.text = text
        self.x = -50
        self.y = randint(20, 380)
        self.color = Color.rand_color()
        self.speed = randint(1, 5)
        self.alive = True

    def move(self):
        self.x += self.speed
        # 越界处理
        if self.x > 600 + 50:
            self.alive = False


class ConversationThread(Thread):
    """处理不同的客户消息"""
    all_message = []
    flag = True

    def __init__(self, conversation: socket.socket, address):
        super().__init__()
        self.conversation = conversation
        self.address = address

    def run(self):
        """服务器与客户端持续通话"""
        while ConversationThread.flag:
            try:
                re_message = self.conversation.recv(1024).decode(encoding='utf-8')
                # 接收到一个消息便创建一个消息对象
                message = Message(re_message)
                # print(re_message)
                # 保存所有的消息
                ConversationThread.all_message.append(message)

                self.conversation.send("".encode())
            except ConnectionResetError:
                print("%s已下线" % self.address)

        print('退出会话线程!')


class AcceptThread(Thread):
    """接收请求的线程类"""
    all_client = []  # 保存所有的用户端

    def __init__(self, server: socket.socket):
        super().__init__()
        self.server = server
        self.flag = True

    def run(self):
        while self.flag:
            conversation, address = self.server.accept()
            print('接收到%s的请求' % address)

            # 接收到一个客户端请求,便创建一个子线程实现会话功能
            t1 = ConversationThread(conversation, address)
            t1.start()
            AcceptThread.all_client.append(t1)

        # 关闭服务器之前,给所有的客户端发送消息
        for tt in AcceptThread.all_client:
            try:
                tt.conversation.send("服务器将关闭,请及时下线!!!".encode())
            except:
                pass
        print('退出请求线程!!')

颜色类

from random import randint


class Color:
    """颜色类"""
    white = 255, 255, 255

    @staticmethod
    def rand_color():
        return randint(0, 255), randint(0, 255), randint(0, 255)

客户端

import socket

if __name__ == '__main__':
    client = socket.socket()
    client.connect(('10.7.181.56', 8088))
    while True:
        # 发送消息
        message = input('>>>')
        client.send(message.encode())

        # 接收消息
        re_message = client.recv(1024).decode(encoding='utf-8')
        print(re_message)

上一篇 下一篇

猜你喜欢

热点阅读