使用Python可以在局域網內實現遠程監控電腦屏幕。以下是兩種實現方法:
方法一:使用mss和socket實現屏幕共享
服務端(被監控端)
import mss
import mss.tools
import socket
import threading
import time
import zlib
class ScreenServer:
def __init__(self, host='0.0.0.0', port=5000):
self.host = host
self.port = port
self.running = False
self.server_socket = None
self.quality = 50 # 圖像質量 (0-100)
def start_server(self):
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(5)
print(f"屏幕共享服務器啓動在 {self.host}:{self.port}")
self.running = True
while self.running:
try:
client_socket, addr = self.server_socket.accept()
print(f"新的連接來自: {addr}")
# 為每個客户端創建新線程
client_thread = threading.Thread(
target=self.handle_client,
args=(client_socket,)
)
client_thread.daemon = True
client_thread.start()
except Exception as e:
if self.running:
print(f"接受連接時出錯: {e}")
def handle_client(self, client_socket):
try:
with mss.mss() as sct:
# 獲取所有顯示器
monitors = sct.monitors
# 使用主顯示器
monitor = monitors[1] # 索引0是所有顯示器的合併區域,索引1是主顯示器
while self.running:
# 捕獲屏幕
screenshot = sct.grab(monitor)
# 轉換為PNG並壓縮
png_data = mss.tools.to_png(screenshot.rgb, screenshot.size)
compressed_data = zlib.compress(png_data, level=zlib.Z_BEST_COMPRESSION)
# 發送數據大小和數據
size_data = len(compressed_data).to_bytes(4, byteorder='big')
client_socket.send(size_data + compressed_data)
# 控制幀率
time.sleep(0.05) # 約20FPS
except Exception as e:
print(f"處理客户端時出錯: {e}")
finally:
client_socket.close()
def stop_server(self):
self.running = False
if self.server_socket:
self.server_socket.close()
if __name__ == "__main__":
server = ScreenServer()
try:
server.start_server()
except KeyboardInterrupt:
server.stop_server()
print("服務器已停止")
客户端(監控端)
import socket
import cv2
import numpy as np
import zlib
import threading
class ScreenClient:
def __init__(self, server_ip, server_port=5000):
self.server_ip = server_ip
self.server_port = server_port
self.running = False
self.client_socket = None
def connect(self):
try:
self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.client_socket.connect((self.server_ip, self.server_port))
self.running = True
print(f"已連接到服務器 {self.server_ip}:{self.server_port}")
return True
except Exception as e:
print(f"連接失敗: {e}")
return False
def receive_screen(self):
try:
while self.running:
# 接收數據大小
size_data = self.client_socket.recv(4)
if not size_data:
break
data_size = int.from_bytes(size_data, byteorder='big')
# 接收壓縮的圖像數據
received_data = b""
while len(received_data) < data_size:
chunk = self.client_socket.recv(min(4096, data_size - len(received_data)))
if not chunk:
break
received_data += chunk
if len(received_data) != data_size:
print("數據接收不完整")
continue
# 解壓並解碼圖像
decompressed_data = zlib.decompress(received_data)
nparr = np.frombuffer(decompressed_data, np.uint8)
frame = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
if frame is not None:
cv2.imshow('遠程桌面', frame)
# 按'q'退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
except Exception as e:
print(f"接收數據時出錯: {e}")
finally:
self.close()
def close(self):
self.running = False
if self.client_socket:
self.client_socket.close()
cv2.destroyAllWindows()
if __name__ == "__main__":
# 替換為服務端的IP地址
server_ip = "192.168.1.100"
client = ScreenClient(server_ip)
if client.connect():
client.receive_screen()
方法二:使用PyAutoGUI和Flask實現Web界面監控
服務端(被監控端)
from flask import Flask, Response
import pyautogui
import cv2
import numpy as np
import threading
import time
app = Flask(__name__)
class ScreenStreamer:
def __init__(self):
self.frame = None
self.running = True
def capture_screen(self):
while self.running:
# 截取屏幕
screenshot = pyautogui.screenshot()
# 轉換為OpenCV格式
frame = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)
# 編碼為JPEG
_, jpeg = cv2.imencode('.jpg', frame, [cv2.IMWRITE_JPEG_QUALITY, 70])
self.frame = jpeg.tobytes()
time.sleep(0.1) # 控制幀率
def get_frame(self):
return self.frame
def stop(self):
self.running = False
streamer = ScreenStreamer()
def generate_frames():
while True:
frame = streamer.get_frame()
if frame:
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
@app.route('/')
def index():
return '''
<html>
<head>
<title>遠程桌面監控</title>
</head>
<body>
<h1>遠程桌面監控</h1>
<img src="/video_feed" width="80%">
</body>
</html>
'''
@app.route('/video_feed')
def video_feed():
return Response(generate_frames(),
mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
# 啓動屏幕捕獲線程
capture_thread = threading.Thread(target=streamer.capture_screen)
capture_thread.daemon = True
capture_thread.start()
# 啓動Flask服務器
app.run(host='0.0.0.0', port=5000, threaded=True)
安裝必要的庫
pip install mss opencv-python pyautogui flask pillow zlib
使用説明
- 方法一:
- 在被監控電腦上運行服務端代碼
- 在監控電腦上運行客户端代碼,並設置正確的服務端IP地址
- 客户端會顯示一個窗口展示遠程桌面
- 方法二:
- 在被監控電腦上運行Flask服務端
- 在瀏覽器中訪問
http://被監控電腦IP:5000即可查看遠程桌面
注意事項
- 安全性:這些代碼僅用於學習和授權的監控用途,請確保你有權限監控目標電腦
- 性能:屏幕共享可能會佔用較多網絡帶寬,請根據網絡情況調整圖像質量和幀率
- 防火牆:確保相關端口(如5000)在防火牆中已開放
優化建議
- 可以根據網絡狀況動態調整圖像質量
- 可以只傳輸屏幕變化的部分以減少數據量
- 可以添加身份驗證機制增強安全性
- 對於高分辨率屏幕,可以考慮縮放圖像以減少數據量