美文网首页
主机A操控主机B同步程序1.0

主机A操控主机B同步程序1.0

作者: Noza_ea8f | 来源:发表于2025-01-02 08:47 被阅读0次

主机A

import socket
import threading
import mouse
import time
from pynput import keyboard


class RemoteMouseClient:
    def __init__(self, server_ip, server_port):
        self.server_ip = server_ip
        self.server_port = server_port
        self.server_socket = None
        self.is_running = True
        self.lock = threading.Lock()  # 增加锁机制
        self.unacknowledged_messages = []  # 存储未确认消息

    def connect_to_server(self):
        while self.is_running:
            try:
                self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.server_socket.connect((self.server_ip, self.server_port))
                print(f"成功连接到服务器 {self.server_ip}:{self.server_port}")
                threading.Thread(target=self.receive_acknowledgements).start()
                break
            except socket.error as e:
                print(f"无法连接到服务器,正在重试... 错误: {e}")
                time.sleep(5)  # 5秒后重试连接

    def send_event(self, message):
        with self.lock:
            self.unacknowledged_messages.append(message)

        self.send_message(message)

    def send_message(self, message):
        if self.server_socket:
            try:
                self.server_socket.send(message.encode())
            except socket.error as e:
                print(f"发送数据时出错: {e}")
                self.server_socket.close()
                self.connect_to_server()  # 重新连接服务器

    def receive_acknowledgements(self):
        while self.is_running:
            try:
                data = self.server_socket.recv(1024).decode()
                if data:
                    with self.lock:
                        if data in self.unacknowledged_messages:
                            self.unacknowledged_messages.remove(data)
            except socket.error as e:
                print(f"接收确认消息时出错: {e}")
                break

    def track_mouse(self):
        def on_move(event):
            if isinstance(event, mouse.MoveEvent):
                x, y = event.x, event.y
                self.send_event(f'move,{x},{y},0,0')

        def on_click(event):
            if isinstance(event, mouse.ButtonEvent):
                x, y = mouse.get_position()  # 获取当前鼠标位置
                if event.event_type == mouse.DOWN:
                    self.send_event(f'{event.button}_down,{x},{y},0,0')
                elif event.event_type == mouse.UP:
                    self.send_event(f'{event.button}_up,{x},{y},0,0')

        def on_scroll(event):
            if isinstance(event, mouse.WheelEvent):
                x, y = event.x, event.y
                self.send_event(f'scroll,{x},{y},{event.delta_x},{event.delta_y}')

        mouse.hook(on_move)
        mouse.hook(on_click)
        mouse.hook(on_scroll)

        while self.is_running:
            time.sleep(1)  # Keep the thread running

    def track_keyboard(self):
        def on_press(key):
            try:
                self.send_event(f'key_down,{key.char}')
            except AttributeError:
                self.send_event(f'key_down,{key.name}')

        def on_release(key):
            try:
                self.send_event(f'key_up,{key.char}')
            except AttributeError:
                self.send_event(f'key_up,{key.name}')

        with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
            listener.join()

    def start(self):
        self.connect_to_server()
        mouse_thread = threading.Thread(target=self.track_mouse)
        mouse_thread.start()
        keyboard_thread = threading.Thread(target=self.track_keyboard)
        keyboard_thread.start()

    def stop(self):
        self.is_running = False
        if self.server_socket:
            self.server_socket.close()


if __name__ == "__main__":
    client = RemoteMouseClient('172.18.254.19', 12345)
    try:
        client.start()
    except KeyboardInterrupt:
        client.stop()
        print("客户端已停止。")

主机B

import socket
import threading
import pyautogui
import pystray
from PIL import Image, ImageDraw
from pynput.keyboard import Controller as KeyboardController, Key
import sys

# 客户端监听的端口
client_listen_port = 12345

# 创建一个事件来控制线程的运行
stop_event = threading.Event()

keyboard_controller = KeyboardController()


def receive_commands():
    listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    listen_socket.bind(('0.0.0.0', client_listen_port))
    listen_socket.listen(5)
    print(f"Listening for commands on port {client_listen_port}")

    while not stop_event.is_set():
        conn, addr = listen_socket.accept()
        threading.Thread(target=handle_command, args=(conn,)).start()


def handle_command(conn):
    while not stop_event.is_set():
        try:
            data = conn.recv(1024).decode()
            if not data:
                break
            parts = data.split(',')
            action = parts[0]

            if action.startswith('key'):
                key = parts[1]
                handle_keyboard(action, key)
            else:
                x, y = int(parts[1]), int(parts[2])
                dx, dy = int(parts[3]), int(parts[4])
                handle_mouse(action, x, y, dx, dy)

            # 发送确认消息
            conn.send(data.encode())
        except Exception as e:
            print(f"处理命令时出错: {e}")
            break
    conn.close()


def handle_mouse(action, x, y, dx, dy):
    if action == 'move':
        pyautogui.moveTo(x, y)
    elif action.startswith('left') or action.startswith('right') or action.startswith('middle'):
        button = action.split('_')[0]
        if 'down' in action:
            pyautogui.mouseDown(x, y, button=button)
        elif 'up' in action:
            pyautogui.mouseUp(x, y, button=button)
    elif action == 'scroll':
        pyautogui.scroll(dy, x, y)


def handle_keyboard(action, key):
    try:
        if len(key) == 1:  # 单个字符键
            if action == 'key_down':
                keyboard_controller.press(key)
            elif action == 'key_up':
                keyboard_controller.release(key)
        else:  # 特殊键
            key = getattr(Key, key, None)
            if key:
                if action == 'key_down':
                    keyboard_controller.press(key)
                elif action == 'key_up':
                    keyboard_controller.release(key)
    except AttributeError as e:
        print(f"按键处理时出错: {e}")


def create_image(width, height, color1, color2):
    image = Image.new('RGB', (width, height), color1)
    dc = ImageDraw.Draw(image)
    dc.rectangle((width // 2, 0, width, height // 2), fill=color2)
    dc.rectangle((0, height // 2, width // 2, height), fill=color2)
    return image


def on_quit(icon, item):
    stop_event.set()  # 设置停止事件
    icon.stop()
    sys.exit()


# 创建系统托盘图标
icon_image = create_image(64, 64, 'blue', 'black')
menu = pystray.Menu(pystray.MenuItem('Quit', on_quit))
icon = pystray.Icon("RemoteMouseClient", icon_image, "客户端", menu)

# 启动命令接收线程
receive_thread = threading.Thread(target=receive_commands, daemon=True)
receive_thread.start()

# 启动系统托盘图标
icon.run()

# 保持主线程运行
while not stop_event.is_set():
    pass


# pyinstaller --onefile --noconsole 客户端v4.0.py

服务器4.1

import socket
import threading
import mouse
import time
from pynput import keyboard
import tkinter as tk
from tkinter import ttk


class RemoteMouseClient:
    def __init__(self, server_ip, server_port):
        self.server_ip = server_ip
        self.server_port = server_port
        self.server_socket = None
        self.is_running = False  # 初始状态为未运行
        self.lock = threading.Lock()  # 增加锁机制
        self.unacknowledged_messages = []  # 存储未确认消息

    def connect_to_server(self):
        """
        尝试连接到服务器,如果连接失败则每隔5秒重试。
        """
        while self.is_running:
            try:
                self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.server_socket.connect((self.server_ip, self.server_port))
                print(f"成功连接到服务器 {self.server_ip}:{self.server_port}")
                self.update_status("已经建立了连接")
                self.update_connected_host_info()
                threading.Thread(target=self.receive_acknowledgements).start()
                break
            except socket.error as e:
                print(f"无法连接到服务器,正在重试... 错误: {e}")
                self.update_status("连接已断开")
                time.sleep(5)  # 5秒后重试连接

    def send_event(self, message):
        """
        将事件消息发送到服务器,并添加到未确认消息列表中。
        """
        with self.lock:
            self.unacknowledged_messages.append(message)
        self.send_message(message)

    def send_message(self, message):
        """
        发送消息到服务器,并在发送失败时重新连接服务器。
        """
        if self.server_socket and self.is_running:
            try:
                self.server_socket.send(message.encode())
            except socket.error as e:
                print(f"发送数据时出错: {e}")
                self.server_socket.close()
                self.connect_to_server()  # 重新连接服务器

    def receive_acknowledgements(self):
        """
        从服务器接收确认消息,并从未确认消息列表中移除确认的消息。
        """
        while self.is_running:
            try:
                data = self.server_socket.recv(1024).decode()
                if data:
                    with self.lock:
                        if data in self.unacknowledged_messages:
                            self.unacknowledged_messages.remove(data)
            except socket.error as e:
                print(f"接收确认消息时出错: {e}")
                break

    def track_mouse(self):
        """
        追踪鼠标事件并发送相应事件消息到服务器。
        """
        def on_move(event):
            if isinstance(event, mouse.MoveEvent):
                x, y = event.x, event.y
                self.send_event(f'move,{x},{y},0,0')

        def on_click(event):
            if isinstance(event, mouse.ButtonEvent):
                x, y = mouse.get_position()  # 获取当前鼠标位置
                if event.event_type == mouse.DOWN:
                    self.send_event(f'{event.button}_down,{x},{y},0,0')
                elif event.event_type == mouse.UP:
                    self.send_event(f'{event.button}_up,{x},{y},0,0')

        def on_scroll(event):
            if isinstance(event, mouse.WheelEvent):
                x, y = event.x, event.y
                self.send_event(f'scroll,{x},{y},{event.delta_x},{event.delta_y}')

        mouse.hook(on_move)
        mouse.hook(on_click)
        mouse.hook(on_scroll)

        while self.is_running:
            time.sleep(1)  # 保持线程运行

    def track_keyboard(self):
        """
        追踪键盘事件并发送相应事件消息到服务器。
        """
        def on_press(key):
            if self.is_running:
                try:
                    self.send_event(f'key_down,{key.char}')
                except AttributeError:
                    self.send_event(f'key_down,{key.name}')

        def on_release(key):
            if self.is_running:
                try:
                    self.send_event(f'key_up,{key.char}')
                except AttributeError:
                    self.send_event(f'key_up,{key.name}')

        with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
            listener.join()

    def start(self):
        """
        启动客户端,连接服务器并开始追踪鼠标和键盘事件。
        """
        self.is_running = True
        self.connect_to_server()
        mouse_thread = threading.Thread(target=self.track_mouse)
        mouse_thread.start()
        keyboard_thread = threading.Thread(target=self.track_keyboard)
        keyboard_thread.start()

    def stop(self):
        """
        停止客户端,断开与服务器的连接。
        """
        self.is_running = False
        if self.server_socket:
            self.server_socket.close()
        self.update_status("连接已断开")
        self.update_connected_host_info(reset=True)

    def update_status(self, status):
        """
        更新GUI中的连接状态。
        """
        if gui:
            gui.update_status(status)

    def update_connected_host_info(self, reset=False):
        """
        更新GUI中已连接的主机信息。
        """
        if gui:
            if reset:
                gui.update_connected_host_info("连接已断开")
            else:
                gui.update_connected_host_info(f"{self.server_ip}:{self.server_port}")


class RemoteMouseClientGUI:
    def __init__(self, client):
        self.client = client
        self.root = tk.Tk()
        self.root.title("Remote Mouse Client")
        self.root.configure(bg='#ffffff')  # 主界面颜色

        # 设置样式
        style = ttk.Style(self.root)
        style.configure('TLabel', font=('Helvetica', 10), background='#f6f8fa', foreground='#3b71a3')
        style.configure('TButton', font=('Helvetica', 10), background='#f6f8fa', foreground='#3b71a3')
        style.map('TButton', background=[('active', '#e0e4e8')])

        # 创建主框架
        main_frame = tk.Frame(self.root, bg='#f6f8fa', bd=1, relief='solid', highlightthickness=1,
                              highlightbackground='#dce2e8')
        main_frame.pack(fill='both', expand=True, padx=10, pady=10)

        # 创建状态标签
        self.status_label = ttk.Label(main_frame, text="连接状态: 未连接", style='TLabel')
        self.status_label.pack(pady=10)

        # 创建启动按钮
        self.start_button = ttk.Button(main_frame, text="启动连接", command=self.start_connection)
        self.start_button.pack(pady=5)

        # 创建终止按钮
        self.stop_button = ttk.Button(main_frame, text="终止连接", command=self.stop_connection)
        self.stop_button.pack(pady=5)

        # 创建已连接主机标签
        self.connected_host_label = ttk.Label(main_frame, text="已连接主机", anchor='w', style='TLabel')
        self.connected_host_label.pack(fill='x', padx=10)

        # 创建已连接主机信息文本框
        self.connected_host_info = tk.Text(main_frame, height=1, width=30, state='disabled', font=('Helvetica', 10),
                                           bg='#f6f8fa', fg='#3b71a3', bd=0, highlightthickness=1,
                                           highlightbackground='#dce2e8')
        self.connected_host_info.pack(pady=10)

        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
        self.center_window()

    def center_window(self):
        """
        将窗口居中显示。
        """
        self.root.update_idletasks()
        width = self.root.winfo_width()
        height = self.root.winfo_height()
        x = (self.root.winfo_screenwidth() // 2) - (width // 2)
        y = (self.root.winfo_screenheight() // 2) - (height // 2)
        self.root.geometry(f'{width}x{height}+{x}+{y}')

    def start_connection(self):
        """
        启动连接线程。
        """
        threading.Thread(target=self.client.start).start()
        self.update_status("正在尝试连接...")

    def stop_connection(self):
        """
        停止连接。
        """
        self.client.stop()
        self.update_status("连接已断开")

    def update_status(self, status):
        """
        更新连接状态标签的文本。
        """
        self.status_label.config(text=f"连接状态: {status}")

    def update_connected_host_info(self, info):
        """
        更新已连接主机信息文本框的内容。
        """
        self.connected_host_info.config(state='normal')
        self.connected_host_info.delete(1.0, tk.END)
        self.connected_host_info.insert(tk.END, info)
        self.connected_host_info.config(state='disabled')

    def on_closing(self):
        """
        处理窗口关闭事件。
        """
        self.client.stop()
        self.root.destroy()
        print("客户端已停止。")
        self.root.quit()

    def run(self):
        """
        运行GUI主循环。
        """
        self.root.mainloop()


if __name__ == "__main__":
    client = RemoteMouseClient('172.18.254.19', 12345)
    gui = RemoteMouseClientGUI(client)
    try:
        gui.run()
    except KeyboardInterrupt:
        client.stop()
        print("客户端已停止。")

服务器4.2

import socket
import threading
import mouse
import time
from pynput import keyboard
import tkinter as tk
from tkinter import ttk

class RemoteMouseClient:
    def __init__(self, server_ip, server_port):
        self.server_ip = server_ip
        self.server_port = server_port
        self.server_socket = None
        self.is_running = False  # 初始状态为未运行
        self.lock = threading.Lock()  # 增加锁机制
        self.unacknowledged_messages = []  # 存储未确认消息
        self.failed_messages = []  # 存储未成功发送的消息

    def connect_to_server(self):
        while self.is_running:
            try:
                self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)  # 设置SO_KEEPALIVE
                self.server_socket.connect((self.server_ip, self.server_port))
                print(f"成功连接到服务器 {self.server_ip}:{self.server_port}")
                self.update_status("已经建立了连接")
                self.update_connected_host_info()
                threading.Thread(target=self.receive_acknowledgements).start()
                self.resend_failed_messages()  # 重新发送未成功发送的消息
                break
            except socket.error as e:
                print(f"无法连接到服务器,正在重试... 错误: {e}")
                self.update_status("连接已断开")
                time.sleep(5)  # 5秒后重试连接

    def send_event(self, message):
        with self.lock:
            self.unacknowledged_messages.append(message)
        self.send_message(message)

    def send_message(self, message):
        if self.server_socket and self.is_running:
            try:
                self.server_socket.send(message.encode())
            except socket.error as e:
                print(f"发送数据时出错: {e}")
                self.failed_messages.append(message)  # 记录未成功发送的消息
                self.server_socket.close()
                self.connect_to_server()  # 重新连接服务器

    def receive_acknowledgements(self):
        while self.is_running:
            try:
                data = self.server_socket.recv(1024).decode()
                if data:
                    with self.lock:
                        if data in self.unacknowledged_messages:
                            self.unacknowledged_messages.remove(data)
            except socket.error as e:
                print(f"接收确认消息时出错: {e}")
                self.server_socket.close()
                self.connect_to_server()  # 重新连接服务器
                break

    def resend_failed_messages(self):
        """
        重新发送所有未成功发送的消息。
        """
        with self.lock:
            for message in self.failed_messages:
                self.send_message(message)
            self.failed_messages.clear()

    def track_mouse(self):
        def on_move(event):
            if isinstance(event, mouse.MoveEvent):
                x, y = event.x, event.y
                self.send_event(f'move,{x},{y},0,0')

        def on_click(event):
            if isinstance(event, mouse.ButtonEvent):
                x, y = mouse.get_position()  # 获取当前鼠标位置
                if event.event_type == mouse.DOWN:
                    self.send_event(f'{event.button}_down,{x},{y},0,0')
                elif event.event_type == mouse.UP:
                    self.send_event(f'{event.button}_up,{x},{y},0,0')

        def on_scroll(event):
            if isinstance(event, mouse.WheelEvent):
                x, y = event.x, event.y
                self.send_event(f'scroll,{x},{y},{event.delta_x},{event.delta_y}')

        mouse.hook(on_move)
        mouse.hook(on_click)
        mouse.hook(on_scroll)

        while self.is_running:
            time.sleep(1)  # 保持线程运行

    def track_keyboard(self):
        def on_press(key):
            if self.is_running:
                try:
                    self.send_event(f'key_down,{key.char}')
                except AttributeError:
                    self.send_event(f'key_down,{key.name}')

        def on_release(key):
            if self.is_running:
                try:
                    self.send_event(f'key_up,{key.char}')
                except AttributeError:
                    self.send_event(f'key_up,{key.name}')

        with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
            listener.join()

    def start(self):
        self.is_running = True
        self.connect_to_server()
        mouse_thread = threading.Thread(target=self.track_mouse)
        mouse_thread.start()
        keyboard_thread = threading.Thread(target=self.track_keyboard)
        keyboard_thread.start()

    def stop(self):
        self.is_running = False
        if self.server_socket:
            self.server_socket.close()
        self.update_status("连接已断开")
        self.update_connected_host_info(reset=True)

    def update_status(self, status):
        if gui:
            gui.update_status(status)

    def update_connected_host_info(self, reset=False):
        if gui:
            if reset:
                gui.update_connected_host_info("连接已断开")
            else:
                gui.update_connected_host_info(f"{self.server_ip}:{self.server_port}")


class RemoteMouseClientGUI:
    def __init__(self, client):
        self.client = client
        self.root = tk.Tk()
        self.root.title("Remote Mouse Client")
        self.root.configure(bg='#ffffff')  # 主界面颜色

        # 设置样式
        style = ttk.Style(self.root)
        style.configure('TLabel', font=('Helvetica', 10), background='#f6f8fa', foreground='#3b71a3')
        style.configure('TButton', font=('Helvetica', 10), background='#f6f8fa', foreground='#3b71a3')
        style.map('TButton', background=[('active', '#e0e4e8')])

        # 创建主框架
        main_frame = tk.Frame(self.root, bg='#f6f8fa', bd=1, relief='solid', highlightthickness=1,
                              highlightbackground='#dce2e8')
        main_frame.pack(fill='both', expand=True, padx=10, pady=10)

        # 创建状态标签
        self.status_label = ttk.Label(main_frame, text="连接状态: 未连接", style='TLabel')
        self.status_label.pack(pady=10)

        # 创建启动按钮
        self.start_button = ttk.Button(main_frame, text="启动连接", command=self.start_connection)
        self.start_button.pack(pady=5)

        # 创建终止按钮
        self.stop_button = ttk.Button(main_frame, text="终止连接", command=self.stop_connection)
        self.stop_button.pack(pady=5)

        # 创建已连接主机标签
        self.connected_host_label = ttk.Label(main_frame, text="已连接主机", anchor='w', style='TLabel')
        self.connected_host_label.pack(fill='x', padx=10)

        # 创建已连接主机信息文本框
        self.connected_host_info = tk.Text(main_frame, height=1, width=30, state='disabled', font=('Helvetica', 10),
                                           bg='#f6f8fa', fg='#3b71a3', bd=0, highlightthickness=1,
                                           highlightbackground='#dce2e8')
        self.connected_host_info.pack(pady=10)

        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
        self.center_window()

    def center_window(self):
        """
        将窗口居中显示。
        """
        self.root.update_idletasks()
        width = self.root.winfo_width()
        height = self.root.winfo_height()
        x = (self.root.winfo_screenwidth() // 2) - (width // 2)
        y = (self.root.winfo_screenheight() // 2) - (height // 2)
        self.root.geometry(f'{width}x{height}+{x}+{y}')

    def start_connection(self):
        """
        启动连接线程。
        """
        threading.Thread(target=self.client.start).start()
        self.update_status("正在尝试连接...")

    def stop_connection(self):
        """
        停止连接。
        """
        self.client.stop()
        self.update_status("连接已断开")

    def update_status(self, status):
        """
        更新连接状态标签的文本。
        """
        self.status_label.config(text=f"连接状态: {status}")

    def update_connected_host_info(self, info):
        """
        更新已连接主机信息文本框的内容。
        """
        self.connected_host_info.config(state='normal')
        self.connected_host_info.delete(1.0, tk.END)
        self.connected_host_info.insert(tk.END, info)
        self.connected_host_info.config(state='disabled')

    def on_closing(self):
        """
        处理窗口关闭事件。
        """
        self.client.stop()
        self.root.destroy()
        print("客户端已停止。")
        self.root.quit()

    def run(self):
        """
        运行GUI主循环。
        """
        self.root.mainloop()


if __name__ == "__main__":
    client = RemoteMouseClient('172.18.254.19', 12345)
    gui = RemoteMouseClientGUI(client)
    try:
        gui.run()
    except KeyboardInterrupt:
        client.stop()
        print("客户端已停止。")

相关文章

  • TCP三次握手过程

    1,主机A通过向主机B 发送一个含有同步序列号的标志位(SYN)的数据段给主机B ,向主机B 请求建立连接,通过这...

  • TCP,握手,分手

    TCP三次握手过程 1 主机A通过向主机B 发送一个含有同步序列号的标志位的数据段给主机B ,向主机B 请求建立连...

  • TCP三次握手过程

    TCP三次握手过程第一次握手:主机A通过向主机B 发送一个含有同步序列号的标志位的数据段给主机B,向主机B 请求建...

  • TCP连接建立过程

    TCP三次握手过程: 第一次握手:主机A通过向主机B 发送一个含有同步序列号的标志位的数据段给主机B,向主机B 请...

  • ssh建立主机间的互信

    所谓的互信,是指主机A信任主机B,主机B也信任主机A。 主机A信任主机B,那么主机B可以向主机A发起免秘钥验证的上...

  • nc Linux 文件传输另一种解锁方式

    接收主机 A: 发送主机 B: 示例: 主机A IP: 192.168.1.3 主机 B

  • 树莓派超级水冷主机驱动程序更新

    水冷主机驱动程序的更新预告来啦!!!! 全新的水冷驱动程序支持图形化界面操作,让你能更简单的操控自己的超级水冷主机...

  • rsync定时同步/备份异地主机文件

    目的:定时将源主机A的数据同步到备份主机B上,实现自动异地备份操作,为数据安全提供进一步防范。1、编写同步脚本2、...

  • Redis部分同步和全同步

    假设主机A,从机B,C,D,其中该系统已经上线有一部分时间了,B突然掉线,那么B再次恢复连上主机A之后,是要同步掉...

  • python虚拟环境迁移

    主机A的虚拟环境向主机B迁移。 前提条件:主机A和主机B 已经安装了virtualenv 1.主机A操作如下 2....

网友评论

      本文标题:主机A操控主机B同步程序1.0

      本文链接:https://www.haomeiwen.com/subject/jhnxyjtx.html