作者 | 李秋键

责编 | 寇雪芹

头图 | 下载于视觉中国

本项目旨在让大家理解远控软件的原理,通过远控桌面可以实现远程控制我们的电脑,更好更方便的管理电脑。文末将给出初始版的完整代码,需要使用到的其他工具也会有所说明。最终实现的效果就是只要用户点击了客户端的程序运行,我们就可以在服务端对其进行控制。效果如下:左边是客服端程序运行了,然后我们就可以在左边的另一台电脑上打开服务端程序进行控制,可以看到左边的屏幕图像也已经显示在了右边的电脑上。完整代码见文末!

远控流程

1.1 环境要求

本次环境使用的是python3.6.5+windows平台

主要用的库有:图像处理库opencv,包括用来目标检测和图像处理等操作。

Socket用来远程传输数据达到远程控制的效果;

Threading模块用来创建多线程管理;

Numpy模块用来辅助opencv对图像进行一些像素值操作;

PIL模块用来获取屏幕图像数据;

pynput.mouse用来控制鼠标点击事件。达到远程控制鼠标的作用。

1.2 客户端讲解

客户端在这里指的是被控制的电脑,就是我们需要受到控制的电脑。

(1)首先是导入相关模块:

1#客户端代码
2import socket
3import threading
4import cv2
5import numpy as np
6from PIL import ImageGrab
7from pynput.mouse import Button,Controller

(2)接着创建一个鼠标控制器和用来接收服务端数据的函数。因为需要一直都接收数据,故需要嵌入循环。在这里客户端还需要接收数据的原因是,用来接收服务端传来的鼠标控制信息,要不然怎么实现鼠标控制桌面的效果呢。

 1#接受服务器返回的数据的函数2m = Controller()3def recvlink(client):4    while True:5        msg=client.recv(1024)6        msg=msg.decode('utf-8')7        print(msg)8        key = msg.split(",")9        xp = int(key[0])
10        yp = int(key[1])
11        m.position = ((xp,yp))
12        m.click(Button.left,1)

(3)创建ipv4的socket对象,使用TCP协议(SOCK_STREAM)。然后设置服务端IP地址,以及端口。这里用来向服务端传输数据,即传输桌面图像数据。注释代码如下:

 1#创建ipv4的socket对象,使用TCP协议(SOCK_STREAM)2client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)3#设置服务器ip地址,注意应该是服务器的公网ip4host='服务器的公网ip'5#设置要发送到的服务器端口,需要在云服务器管理界面打开对应端口的防火墙6port=设置的端口7#建立TCP协议连接,这时候服务器就会监听到到连接请求,并开始等待接受client发送的数据8client.connect((host,port))9#建立连接后,服务器端会返回连接成功消息
10start_msg=client.recv(1024)
11print(start_msg.decode('utf-8'))
12#开启一个线程用来接受服务器发来的消息
13t=threading.Thread(target=recvlink,args=(client,))
14t.start()
15p = ImageGrab.grab()#获得当前屏幕
16quality = 25  # 图像的质量
17encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), quality]
18while True:
19    im = ImageGrab.grab()
20    imm=cv2.cvtColor(np.array(im), cv2.COLOR_RGB2BGR)#转为opencv的BGR格式
21    imm = cv2.resize(imm, (1535, 863))
22    img_encode = cv2.imencode(".jpg", imm, encode_param)[1]
23    data_encode = np.array(img_encode)
24    str_encode = data_encode.tostring()
25    #print(len(str_encode))
26    #输入要发送的信息
27    sendmsg="kehu"
28    #向服务器发送消息
29    client.send(str_encode)
30    if sendmsg=='quit':
31        break
32#结束时关闭客户端
33client.close()

1.3 服务端讲解

服务端指的是用来控制远程电脑的那一端,为了方便使用,我们直接在服务器上使用即可。

(1)导入使用到的模块:

1#服务器端
2import socket
3import threading
4import numpy as np
5import cv2
6import os

(2)创建鼠标点击事件函数,用来获取鼠标点击的位置坐标:

1print("等待连接---")
2def mouse_click(event, x, y, flags, para):
3    if event == cv2.EVENT_LBUTTONDOWN:  # 左边鼠标点击
4        f=open("1.txt","w")
5        f.write(str(x)+","+str(y))
6        f.close()

(3)创建服务器端接收数据函数,用来实时接收传输过来的图像数据并显示:

 1def recv_msg(clientsocket):2    while True:3        # 接受客户端消息,设置一次最多接受10240字节的数据4        recv_msg = clientsocket.recv(102400)5        # 把接收到的东西解码6        msg = np.fromstring(recv_msg, np.uint8)7        img_decode = cv2.imdecode(msg, cv2.IMREAD_COLOR)8        try:9            s=img_decode.shape
10            img_decode=img_decode
11            temp=img_decode
12        except:
13            img_decode=temp
14            pass
15        cv2.imshow('SERVER', img_decode)
16        cv2.setMouseCallback("SERVER", mouse_click)
17        try:
18            f=open("1.txt")
19            txt=f.read()
20            f.close()
21            reply=txt
22            print(reply)
23            clientsocket.send(reply.encode('utf-8'))
24            os.remove("1.txt")
25        except:
26            pass
27        if cv2.waitKey(1) & 0xFF == ord('q'):
28            break

(4)主函数,用来建立连接和数据接收等功能。

 1def main():2    socket_server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)3    host='服务器的本地ip'4    #设置被监听的端口号,小于1024的端口号不能使用5    port=设置的端口6    socket_server.bind((host,port))7    #设置最大监听数,也就是最多可以同时响应几个客户端请求,一般配合多线程使用8    socket_server.listen(5)9    #等待客户端连接,一旦有了连接就立刻向下执行,否则等待
10    #accept()函数会返回一个元组,第一个元素是客户端socket对象,第二个元素是客户端地址(ip地址+端口号)
11    clientsocket,addr=socket_server.accept()
12    # 有了客户端连接后之后才能执行以下代码,我们先向客户端发送连接成功消息
13    clientsocket.send('连接成功'.encode('utf-8'))
14    # 和客户端一样开启一个线程接受客户端的信息
15    t=threading.Thread(target=recv_msg,args=(clientsocket,))
16    t.start()

远程控制GUI窗口

远控桌面GUI主要是为了美观而用,需要大家根据远程代码进行集合修改。当然单独使用上述代码已经可以实现功能了,只是不够美观。由于考虑到此处代码量较大,且不是重点,故粗略讲解

(1)导入相关库:

 1from PyQt5.QtWidgets import *2from PyQt5.QtCore import *3from PyQt5.QtGui import QPalette, QBrush, QPixmap4import os5import socket6import threading7import cv28import numpy as np9from PIL import ImageGrab
10from pynput.mouse import Button,Controller
11import time

(2)建立鼠标控制函数和点击函数

1m = Controller()
2def mouse_click(event, x, y, flags, para):
3    if event == cv2.EVENT_LBUTTONDOWN:  # 左边鼠标点击
4        print( x, y)
5        m.position = (x, y)
6        time.sleep(0.1)
7        m.click(Button.left, 1)

(3)GUI界面初始化,由于我们需要把实时的视频显示在窗口上,故也需要使用到opencv。

 1def __init__(self, parent=None):2    super(Ui_MainWindow, self).__init__(parent)3    # self.face_recong = face.Recognition()4    self.timer_camera = QtCore.QTimer()5    self.cap = cv2.VideoCapture()6    self.CAM_NUM = 07    self.set_ui()8    self.slot_init()9    self.__flag_work = 0
10    self.x = 0
11    self.count = 0

(4)设置窗口大小和控件位置等信息。创建布局和设置名称

 1def set_ui(self):2    self.__layout_main = QtWidgets.QHBoxLayout()3    self.__layout_fun_button = QtWidgets.QVBoxLayout()4    self.__layout_data_show = QtWidgets.QVBoxLayout()5    self.button_open_camera = QtWidgets.QPushButton(u'远程桌面')6    self.button_close = QtWidgets.QPushButton(u'退出')7    # Button 的颜色修改8    button_color = [self.button_open_camera, self.button_close]9    for i in range(2):
10        button_color[i].setStyleSheet("QPushButton{color:black}"
11                                      "QPushButton:hover{color:red}"
12                                      "QPushButton{background-color:rgb(78,255,255)}"
13                                      "QPushButton{border:2px}"
14                                      "QPushButton{border-radius:10px}"
15                                      "QPushButton{padding:2px 4px}")
16    self.button_open_camera.setMinimumHeight(50)
17    self.button_close.setMinimumHeight(50)
18    # move()方法移动窗口在屏幕上的位置到x = 300,y = 300坐标。
19    self.move(500, 500)
20    # 信息显示
21    self.label_show_camera = QtWidgets.QLabel()
22    self.label_move = QtWidgets.QLabel()
23    self.label_move.setFixedSize(100, 100)
24    self.label_show_camera.setFixedSize(1530,863)
25    self.label_show_camera.setAutoFillBackground(False)
26    self.__layout_fun_button.addWidget(self.button_open_camera)
27    self.__layout_fun_button.addWidget(self.button_close)
28    self.__layout_fun_button.addWidget(self.label_move)
29    self.__layout_main.addLayout(self.__layout_fun_button)
30    self.__layout_main.addWidget(self.label_show_camera)
31    self.setLayout(self.__layout_main)
32    self.label_move.raise_()
33    self.setWindowTitle(u'远控桌面GUI')
34    '''
35    # 设置背景图片
36    palette1 = QPalette()
37    palette1.setBrush(self.backgroundRole(), QBrush(QPixmap('background.jpg')))
38    self.setPalette(palette1)
39    '''

(5)获取鼠标点击时的坐标:

 1def mousePressEvent(self,event):2    if event.buttons() & QtCore.Qt.LeftButton:3        x = event.x()-1204        y = event.y()-105        text = "x: {0},y: {1}".format(x,y)6        if x>=0 and y>=0:7            m.position = (x, y)8            time.sleep(0.1)9            m.click(Button.left, 1)
10        print(text)

(6)按钮绑定所设置的函数:

1def slot_init(self):
2    self.button_open_camera.clicked.connect(self.button_open_camera_click)
3    self.timer_camera.timeout.connect(self.show_camera)
4    self.button_close.clicked.connect(self.close)

(7)显示桌面功能函数,并设置点击时修改名称,可以随时关闭桌面

1def button_open_camera_click(self):
2    if self.timer_camera.isActive() == False:
3        self.timer_camera.start(30)
4        self.button_open_camera.setText(u'关闭')
5    else:
6        self.timer_camera.stop()
7        self.cap.release()
8        self.label_show_camera.clear()
9        self.button_open_camera.setText(u'远程桌面')

(8)显示桌面函数和退出程序函数

 1def show_camera(self):2    im = ImageGrab.grab()3    imm = cv2.cvtColor(np.array(im), cv2.COLOR_RGB2BGR)  # 转为opencv的BGR格式4    #imm = cv2.resize(imm, (1535, 863))5    self.image = imm6    # face = self.face_detect.align(self.image)7    # if face:8    #     pass9    show =cv2.resize(self.image, (1536,863))
10    show = cv2.cvtColor(show, cv2.COLOR_BGR2RGB)
11    print(show.shape[1], show.shape[0])
12    # show.shape[1] = 640, show.shape[0] = 480
13    showImage = QtGui.QImage(show.data, show.shape[1], show.shape[0], QtGui.QImage.Format_RGB888)
14    self.label_show_camera.setPixmap(QtGui.QPixmap.fromImage(showImage))
15    #cv2.setMouseCallback(showImage, mouse_click)
16    # self.x += 1
17    # self.label_move.move(self.x,100)
18    # if self.x ==320:
19    #     self.label_show_camera.raise_()
20def closeEvent(self, event):
21    ok = QtWidgets.QPushButton()
22    cacel = QtWidgets.QPushButton()
23    msg = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Warning, u"关闭", u"是否关闭!")
24    msg.addButton(ok, QtWidgets.QMessageBox.ActionRole)
25    msg.addButton(cacel, QtWidgets.QMessageBox.RejectRole)
26    ok.setText(u'确定')
27    cacel.setText(u'取消')
28    # msg.setDetailedText('sdfsdff')
29    if msg.exec_() == QtWidgets.QMessageBox.RejectRole:
30        event.ignore()
31    else:
32        #             self.socket_client.send_command(self.socket_client.current_user_command)
33        if self.cap.isOpened():
34            self.cap.release()
35        if self.timer_camera.isActive():
36            self.timer_camera.stop()
37        event.accept()

完整代码下载链接:https://pan.baidu.com/s/1r_ZAfWQG-xYGmYlZCDmWTQ,提取码:lnp4

作者简介:李秋键,CSDN博客专家,CSDN达人课作者。硕士在读于中国矿业大学,开发有taptap竞赛获奖等。

在第 111 个女神节到来之际,CSDN 向所有技术女神致敬!并特邀产学研界的技术女神代表,共同探讨女性开发者的职业发展机遇与挑战,助力更多程序媛谱写精彩的程序人生。

☞腾讯回应两块八卖《鬼谷八荒》:已下架并退款;iMac Pro 售完即停产;iCloud 识别姓氏闹乌龙 | 极客头条
☞腾讯:这可是一只“骨骼清奇”的狗
☞《互联网人求职图鉴》:这类人才“最吃香”,最高薪编程语言出炉!
☞Google 重磅发布 Flutter 2 !一套代码横扫 5 大系统

Python 手把手实现远程控制桌面相关推荐

  1. Python手把手实现远程控制桌面

    作者 | 李秋键 责编 | 寇雪芹 头图 | 下载于视觉中国 引言: 本项目旨在让大家理解远控软件的原理,通过远控桌面可以实现远程控制我们的电脑,更好更方便的管理电脑.文末将给出初始版的完整代码,需要 ...

  2. 远控桌面服务器,Python 手把手实现远程控制桌面

    作者 | 李秋键 责编 | 寇雪芹 头图 | 下载于视觉中国 本项目旨在让大家理解远控软件的原理,通过远控桌面可以实现远程控制我们的电脑,更好更方便的管理电脑.文末将给出初始版的完整代码,需要使用到的 ...

  3. python电脑版微信-python如何实现远程控制电脑(结合微信)

    不知道大家有没有这样一个烦恼,"自己的电脑总是被别人使用,又不好意思设置密码",所以利用python设计了一个程序来实现自由管控. 功能虽然简单,但大家可以通过其思路来实现更多的功 ...

  4. 如何在 Python 中构建跨平台桌面应用程序

    如何在 Python 中构建跨平台桌面应用程序 开发桌面 GUI 应用程序曾经是一个乏味.容易出错且缓慢的过程. 当然,Python 在整体上极大地简化了应用程序开发,但在 GUI 领域,仍然没有真正 ...

  5. 部署Guacamole远程控制桌面

    部署Guacamole远程控制桌面 ------基于Ubuntu 16.04 所有方式均在root权限下进行 1.     下载安装包: apt-get install guacamole-tomca ...

  6. 帮你解剖Python的一个轻量级桌面GUI开发第三方库:Eel,让它体无完肤

    Python的一个轻量级桌面GUI开发第三方库:Eel 一.Eel介绍 二.资源库eel的安装 三.文件结构和简单的hello介绍 3.1 文件结构 3.2 代码:hello1.py 3.3 main ...

  7. 运用python爬取彼岸桌面所有关键字高清壁纸

    运用python爬取彼岸桌面所有关键字高清壁纸 第一次在csdn写博客, 个人技术并不成熟, 还是学生, 高手轻喷菜鸡勿啄 就是心血来潮想要换桌面壁纸, 存在一个文件夹自动更换, 但是从网站上一个一个 ...

  8. 基于Python打印文字到桌面壁纸上的提醒学习小程序

    想法起点 最近本人在B站上边学习JAVA,但苦于JAVA有上百多P的选集 每次看完课关掉浏览器都必须将当前页面添加到收藏夹,然后再删掉之前保存的链接 在密密麻麻的小框框里一个一个点是真的不舒服,还容易 ...

  9. Python+WebKit+HTML开发桌面应用程序

    Python+WebKit+HTML开发桌面应用程序 前言 几天前写了一个备份的小工具,用Python写个脚本,也就花个一天的时间搞定,给客户用了一下,对功能很满意,但对界面不满足,想要一个图形界面来 ...

最新文章

  1. 起售价近5500,嘲讽了iPhone X的华为Mate 10却没用上人脸识别
  2. DHCP欺骗(DHCP Sproofing)
  3. 通过WebRTC实现实时视频通信(三)
  4. 数位屏如何去光标_iPad还是数位板屏?我该选哪个?
  5. 权限控制的两种主要方式详述
  6. 【ArcGIS遇上Python】ArcGIS Python中文编码问题案例详解
  7. [Vue进阶]为什么我的代码让别人看起来头皮发麻?
  8. 计算机漏洞为什么无法避免,雷电3接口漏洞影响数百万计算机:5分钟解锁设备,无法修复...
  9. D - Maze(深度搜索+思维转换)
  10. Network Delay Time
  11. 使用darknet批量测试图片并保存在指定文件夹下
  12. 汇编语言程序设计基础知识
  13. Mybatis-plus 苞米豆生态圈
  14. android 调用hal,Android HAL层的使用方法总结
  15. 系统集成16真题解析
  16. android 九宫格图案解锁
  17. 华为鸿蒙新机2k曲面屏,华为P40系列“登场”:2K曲面屏+前后8摄,鸿蒙系统就别想了...
  18. mysql删除关键字记录,在MySQL删除表语句中,下列选项用于删除表的结构和记录数据全部,并且不能恢复的是( )关键字。...
  19. Java 8 的异步编程利器 CompletableFuture 真香!
  20. 编译原理实验Sicily--LR(K) 语法分析程序

热门文章

  1. 安卓开发—根据顾客预算显示食物信息
  2. CleanCodeHandbook Chapter 9: Binary Search(48-50)
  3. Struts2学习笔记(六) 结果(Result)(上)
  4. 腾讯-004-两个排序数组的中位数
  5. 类的实例属性和类属性的区别
  6. TableViewCell,TableView,UITableViewCell
  7. 如何去定义一个jquery插件
  8. 项目交换成功——PM(李忠)
  9. 性能测试工具AlldayTest 的测试方法及说明
  10. 《TensorFlow 2.0深度学习算法实战教材》学习笔记(五、神经网络)