202302262120

\关于图像编码问题**

\1**

我屏幕分辨率是 1920 1080 3 = 6220800,所每帧是 6220800/1024/1024 = 5.9M

如果 要60fps的话 则需要每秒传输 5.9M*60 = 360M/s 太大了 明显不可能

所以需要个图片压缩传输

\2**

如果用png压缩的话 是102K 如果60fps的话 则6m/S

也有点大

\3**

我们其实不行呀传送整张图片

我们只需要传送 这帧和上帧的差异部分就可以,这样就可以让传输变得更加快捷

png (im2 - im1)

所以我们选择 numpy 实现两张图片之间做一个减法

而opencv-python可以把两张图片的差 变成图片进行传输

imgimg

Server:

\实现桌面的传输**

\1、对于被控端(server):**

具体步骤:

1、先建立一个套接字

2、实现桌面的截图

3、传输,接受控制端发的信息

4、实现 键盘和鼠标的操作

\、对于 控制端(client):**

具体步骤:

1、建立对应的套接字

2、收到数据流

3、根据套接字编码 而解码,并且监听自己cavas 鼠标 键盘 数据流 且发送给 server

4、通过从cv2.imshow() 进行show

具体的编码:

img

img

这里使用了 tkinter 模块 设置了IP地址 port 和大小等参数 实现了鼠标键盘的交互

img

并且

Client和server 通过并发编程来实现 图形的帧传输

也就是传输视频

以下是代码:

img

imgimg

注意 这里我使用了 struct模块封装 图片 让其成为bytes流

img

再使用了canvas来show 图片

并且在 while ture:

下 ims = cv2.imdecode(data, cv2.IMREAD_COLOR)

​ img = img + ims

​ imt = cv2.resize(img, (w, h))

​ imsh = cv2.cvtColor(imt, cv2.COLOR_RGB2RGBA)

​ imi = Image.fromarray(imsh)

​ imgTK.paste(imi)

来实现了 一直 img.tk.paste

说白了就是只要有新图片传输了 解包了 就在canvas上面展示 这个图片

于是 实现了 图片的快速替换

也就是实现了视频的传输

这是在本机的效果:

img

明显 成功了

C语言编程:

Server.C :img

Client.C:img

使用了传统的套接字,重点就是 我们使用python中的ctypes库 实现了C和python传输

这里我们在linux用 GCC -FPIC -shared server.c -o server.so

把server和client都变成.so文件 也就是linux中的动态链接库

然后我们用server_C.py,client_C.py调用 其中的server.c和client.c

其中 server_C.py和client_C.py的函数体是一样的

img

img都是对其中的调用

而 cdll.loadlibrary 函数 则指定了这两个函数库

img

其中 listenfd server_listenfd 等都是 c_int类型 与C语言模块中socket 中类型一样

img这两个 则是 c_char_p 类型 在C语言对应了 改变的bufsize

以下转换就不一一概述了

这是server_c .py 实现了talk

我使用了python中threading模块 start它 实现了传输和接送的并发

img

Client 同理

代码类似

接下来我们把目光 放到主要的远程控制文件中 在

上面的论述中我们实现了 图形界面的传输

接下来我们要实现 键盘和鼠标 传输和操作

首先是控制端:

我们把tinker模块的canvas 中bind (sequence =”?”,func = ?)这个模块 来 封装

其中sequence 代表的是 键盘事件

其中int参数e代表着 e在canvas中的像素位置

1 是左键 2是右键 如此类推

Func 则对应了此事件发生时引发的函数

这里 我们先封装了 conn 也就是套接字

Eventdo 则是用conn链接的套接字发送其中的信息

其他函数 则是直接发送 e.x/scale 也就是放缩比

得到的值就是 在控制端 鼠标应该出现的位置

左键 右键 滚轮 同理

img

img

然后我们在被控端

接受这些鼠标和键盘的数据流

Socket 套接字部分就不说了和 上述图形传输一样

这里我使用了python中img

来实现鼠标和键盘 的操作

(然后我就发现了一个问题)

在linux 和 windows中 中 python的keyboard对应的值是不同的

于是我在github中

找到了 所有平台对用的keyboard值 并且把他 独立出来 成为一个模块

Github 链接:https://github.com/boppreh/keyboard/tree/master/keyboard

也就是keyboard.py :

img

就这样我知道了 linux 平台是 X11

img

这些就是所有平台的 keycode

于是我又回头在 控制端 设置了平台函数

为了就是 实现 平台中key不错误

解决了keycode问题

我就实现了 img

鼠标和键盘 的按下和弹起操作

到目前为止

我的代码已经完成

当我到虚拟机实验时不出意外的报错了

错误信息是:

img

img

之后我在github上面找到了解决方案:

解决方案链接: https://github.com/python-pillow/Pillow/issues/5130

img

下面的解决方案则是 python中 xdisplay要和linux中的echo $display 参数一样

我估计 :0在Ubuntu中是wayland :1才是 X

imgimg

img

其中我才发现了 unbuntu 居然没用X 而是使用了 wayland

还好找到了这个解决问题的方案 不然就寄了

发现我可以在linux 127.0.0.1 传输视频了

img

当我在两个虚拟机中传输时 又出现了问题:

X connection failed: error 1

后来我通过谷歌 终于发现了解决方法

原来 X 在进行链接的时候要先host+一下 我真是醉了

img

于是在linux 中输入Xhost + 开启所有链接

img

然后再次实验

终于成功了

img

这是 两个虚拟机 右面是被控端 找到ip地址

然后写入 点击show

img

成功控制

img

字符串传输成功

img

成功实现了 远程控制

实验总结:

这次实验我收获非常大

C和python的混合编程

如何图像传输

对C和python中套接字的 理解更上一层 没想到 python的socket和C的socket完全不同 尤其是 C中居然还有个自己的类型

然后就是感谢 下github上那些解决问题的人 没有他们我估计是肯定没法发现这Ubuntu还花活 总而言之 这次收获非常之大

Ps:

我之前曾经实现过 一个反木马 可以用shell操作来实现对于肉鸡的控制 但是总归还是不如 远程链接的控制 来的易操作和获得权限

在我学习 yolo的时候 由于这个小电脑 不能进行跑cuda 于是我把自己的游戏本 放在宿舍 通过img 向日葵这个 来实现远程控制 让自己的游戏本跑 深度学习

之后我就想 我能不能自己写一个 远程控制呢? 还是跨平台的 (向日葵不支持 linux)。

然后感谢 bilibili上面 pysrc大佬,我是向这个大佬是学习 实现了远程链接img