远程协助的奥秘
- 远程协助是什么?
远程协助是在网络上由一台电脑(主控端Remote/客户端)远距离去控制另一台电脑(被控端Host/服务器端)的技术。电脑中的远程控制技术,始于DOS时代。远程控制一般支持下面的这些网络方式:LAN、WAN、拨号方式、互联网方式。(如果不懂,请自行百度。)
- 远程协助的原理是什么?
传统的远程控制软件一般使用NETBEUI、NETBIOS、IPX/SPX、TCP/IP等协议来实现远程控制,不过,随着网络技术的发展,很多远程控制软件提供通过Web页面或者是客户端形式以Java技术来控制远程电脑,这样可以实现不同操作系统下的远程控制,例如向日葵远程控制软件,及支持Web页面远程也支持客户端远程。
简单点说,就是利用互联网七层架构来实现主机与主机之间的数据,状态,互相传送。
-
此处的远程协助是什么?
此处,我利用TCP/IP栈上的UDP协议实现,为什么选择UDP协议呢?UDP协议是一种无连接协议,占用资源少,通信速度快。而为什么没有选择TCP协议实现呢?TCP协议是一种有连接协议,所客户端要始终和受控端相连接,如果受控端过多的话,导致占用资源过多,很容易出现掉线的情况。不仅如此,我们既然做的是远程,那必然需要看到对方电脑或者其他设备的画面,所以要有图像的传输。图像、音频这类对质量要求不高的,对实时性要求较高的,那UDP协议无疑是最好的选择。
讲完了图像,那就谈一谈身份认证、鼠标键盘控制和数据安全传输这三个模块。
我这里的身份认证,是在登录页面有控制端地址、端口、用户名和密码的校验,可以看下图:
有人是不是觉得有些熟悉,没错,我这个是模仿NetScout的页面的,用户名和密码可以借助第三方服务器来进行验证,在明文的基础上适当的加上验证。
而控制这里需要的就更多了,话不多说,看图:
先介绍一下,添加设备,可以连接更多的控制端。连接设备,自然就是能够对控制端进行监视和控制。
数据安全传输自然就是对数据进行加密,允许监听,但是截获的数据包不一定能够被解密。
-
实现过程中遇到的难题有哪些?
- 点击连接设备为什么只出现一次图像就没有了?
只出现一次图像的的源码:
UdpClient Client = new UdpClient();
IPEndPoint remoteHost = new IPEndPoint(IPAddress.Parse(textip), 1025);
byte[] buffer = Encoding.UTF8.GetBytes(DES.encrpytionDES.DESEncrypt(message.ToString()));
Client.Send(buffer, buffer.Length, remoteHost);
Client.Close();
正常后的源码:
public void SendremoteHost(object message)
{
while (true)
{
try
{
UdpClient Client = new UdpClient();
IPEndPoint remoteHost = new IPEndPoint(IPAddress.Parse(textip), 1025);
byte[] buffer = Encoding.UTF8.GetBytes(DES.encrpytionDES.DESEncrypt(message.ToString()));
Client.Send(buffer, buffer.Length, remoteHost);
Client.Close();
}
catch (Exception ex)
{
}
}
}
解释:本来以为,将要执行的函数放在线程池ThreadPool里,并且调用QueueUserWorkItem()这个方法,及应该是每传递一次图像就调用一次线程,但事实上是线程被调用了一次,但SendremoteHost()这个自定义方法也执行了一次,以此需要在方法里多家一层循环,才能保证图像能够实时接收。但是真正意义上的,成熟的,商业化的这些协助工具,基本都会为接收图像事件制定一个时间控制器,在c#语言里就是一个时间控件,只有时间控制好,远程协助的体验才是最好的。
2. 键盘鼠标的控制是怎么实现的?
在面向对象的这些高级语言里,对操作系统的操作都是要调用操作系统底层的API接口的,而鼠标的控制就是下面这个函数了
要想调用鼠标控制对对方的电脑,就要在客户端这里pictruebox控件里确定鼠标的点击、移动等事件。在这些事件里自定义完成的操作。说到鼠标的点击和移动,自然就涉及到鼠标Hook是如何定义的,包括鼠标操作类型,屏幕坐标等,看代码
客户端接收到图像,鼠标点击图像上的按钮,这件操作会转化为二进制流,通过加密信道传输到控制端那里去,控制端那里监听到数据包,解密,分析进行什么样得操作。在这里解释一下mouse_event(int flags,int x,int y,int dzData,int Extrainfo)这个函数,flags代表的是鼠标的操作类型,x代表的是屏幕的x坐标,y代表的是屏幕的坐标,其他可以暂不考虑为0就可以。
键盘的控制的API如下
键盘和鼠标的操作差不多,但是比鼠标更加简化,直接调用keyPress(byte keyName)即可,如果你认为键盘和鼠标的调用事件的方式一样,那可就大错特错了,打开pictruebox控件你会发现根本就没有keydown这类按键事件,看图
在.net平台上这类窗体里的控件大部分都没有keydown事件,只有一个PreviewKeyDown事件,而这个时间是发生在按键之前的,和按键无关,你通过此图发现鼠标事件和键盘事件差别很大。那该怎么办呢,我们不可能不操作键盘吧,所以有一种方法能够解决这个问题,那就是看图
如图,看到键盘按键了吧,再仔细看,会发现这个属性是WinForm窗体本身的,所解决办法有了,就是将按键事件加载在窗体上。但是有大佬肯可能发现,绑定了keydown事件到winform窗体上,为啥键盘按键还是没有反应呢,这是因为看下图
原来键盘事件没有注册。未注册的的大佬请注册,hi hi。
3. 截屏又是怎么实现的呢,我这里只介绍一种截屏方法,话不多说,上源码:
4. 图片是怎么传输的呢,接着上源码:
客户端和控制端都是图片和二进制流进行转换的,通过UDP协议传输数据流。
5. 图片接收为什么会模糊?
那是因为截图的大小是屏幕大小,而我只传输了一个包,这一个包只有64K,所以客户端接收到的图片,可以说是只有真实图片的64/500左右,这个问题目前我的能力有限,尚未及解决,等待那位大佬前来指正。
如有需要
请联系qq邮箱:2590367577@qq.com