guacamole学习小结(一)

一、快速安装

https://blog.csdn.net/qq_38781075/article/details/106459458

二、整体理解

先放一张经典的图。

guacamole最重要的作用还是连接远程服务器的,可以连接多台服务器,连接不同的远程协议的服务器。使得用户能远程快捷的访问远程桌面。它跨越操作系统(web浏览器),然后用户不需要安装什么东西(不同的远程协议的服务器可能要安装一些东西,比如VNC客户端)。

上面这张图是从上往下看的,浏览器(用户)通过guacamole服务器(也就是中间黄色的虚线框里的Guacamole Server)连接到远程桌面(Remote Desktop),并且guacamole支持不同的协议访问远程桌面,如图中的RDP、VNC等等。

而Guacamole Server又分为两个部分,如图,一个是guacd,另外一个中间的Guacamole。中间的Guacamole实际上是部署在Tomcat上的一个web应用,所以Guacamole外面还包了一层蓝灰色的Tomcat,为了避免误解,中间的Guacamole以下简称为web应用。

Guacamole Server的这两个部分,guacd和web应用,可以放在不同的电脑上或者服务器上,它们之间的通信是通过Guacamole协议实现通信。它们又分别拥有不同的功能。

guacd启动的时候会以守护进程的形式存在于机器上。guacd主要负责跟远程桌面的服务器通信,支持不同的远程协议进行通信如RDP、VNC、SSH等,guacd每次跟一台新的机器远程通信的时候,都会建立一个新的进程专门负责跟这新的机器通信。guacd与远程桌面通信的信息,会以Guacamole协议传输的方式先交给web应用,web应用再转换为HTML的形式给用户,用户就能实时操作远程桌面。

web应用是部署在Tomcat上的,主要作用是验证用户的合法性(账号密码等),远程桌面的一些信息(如IP地址、账号密码等)也存在这里。web应用还有一个作用就是跟guacd连接,web应用并不关心远程连接的协议是什么,只需要把guacd传来的信息(Guacamole协议传输的)解析转换成HTML给用户看即可。

三、Guacamole协议

guacamole协议协议大概是这样的,下面是两条示例命令。

6.select,3.vnc;
4.args,13.VERSION_1_1_0,8.hostname,4.port,8.password,13.swap-red-blue,9.read-only;

格式:长度 + 点 +字符串数据

第一个字符串数据是命令,后面的数据都是参数,中间逗号分隔,以分号结尾。

guacamole协议有自己的解析器,能把guacamole协议解析成命令+参数的形式。第一条命令就可以解析成为:select,vnc。

guacamole协议最大的作用就是用来传输图像和命令(用户输入)的,前面说了guacd屏蔽了底层(远程桌面)协议的差异,把远程桌面实时的图像先用guacamole协议传输给web应用,最后web应用以HTML的形式展现给用户。

打个比方,就像一个显示器似的,显示器也不关心跟自己连接的操作系统是什么样的,只要你把图像通过HDMI口或者串口发送给我就行了,我就能正常显示图像。guacamole协议很像显示器的数据线。不过guacamole协议除了能传输图像,还能传输命令,又充当了鼠标键盘的作用。

四、官方测试用例

源文件

https://github.com/apache/guacamole-server/tree/master/src/libguac/tests

这些测试用例主要依赖于官方的一个库——libguac。

append.c

该文件位于parser目录下,主要是关于使用一个解析器的,解析guacamole协议的。

前面说过guacamole协议的格式。

4.test,8.testdata,5.zxcvb,13.guacamoletest;

这个文件主要调用了两个函数

guac_parser* guac_parser_alloc();
int guac_parser_append(guac_parser* parser, void* buffer, int length);

第一个函数主要作用就是申请一个解析器(并且初始化)。

第二个函数,参数有三个,第一个参数是解析器,第二个参数是缓冲区,解析器要解析的缓冲区,第三个参数就是解析器的长度。返回值就是解析的长度。最终解析的数据会存放于解析器里。

解析器是一个结构体,其中里面的state成员变量储存解析器的状态(错误、解析完全等等),opcode成员变量储存解析到的命令,argv成员变量储存解析到的参数,是个变长参数,跟main里面的argv类似。

read.c

该文件位于parser目录下,关于读取guacamole协议。

这个文件主要调用了两个函数

guac_socket* guac_socket_open(int fd);
int guac_parser_read(guac_parser* parser, guac_socket* socket, int usec_timeout);

第一个函数是用来初始化guac_socket,就是官方定义的套接字结构体,参数就传递一个普通的文件描述符(套接字)就行。这个guac_socket除了存储文件描述符,还有初始化一些回调函数,比如读取到数据调用什么函数,发送数据调用什么函数。结构里面还有一些锁,这个函数也会帮忙初始化。

第二个函数有三个参数,分别是解析器,guac_socket,还有超时时间,这个函数融合了解析器和套接字读取数据,就是从套接字读取数据并且解析出来,就是这个函数的作用。返回值-1代表解析失败,0代表成功。

next_free.c

该文件位于pool目录下,教你如何使用整型池。

这个文件主要调用了三个函数

guac_pool* guac_pool_alloc(int size);
int guac_pool_next_int(guac_pool* pool);
void guac_pool_free(guac_pool* pool);

很简单,第一个函数是申请整型池,并且参数就是整型池的大小,第二个函数就是从池里取出一个整数,第三个函数就是把一个整数放回池里。

不管是释放还是取出,都是线程安全的。释放过的整数就能从池子里再取出来。

fd_send_instruction.c

该文件位于socket目录下,讲述发送guacamole协议的报文。

这个文件主要调用了三个函数

int guac_protocol_send_name(guac_socket* socket, const char* name);
int guac_protocol_send_sync(guac_socket* socket, guac_timestamp timestamp);
ssize_t guac_socket_flush(guac_socket* socket);

前面两个函数其实可以合并一块讲,发送guacamole协议的报文,其中guacamole协议有命令和参数的部分,这些函数就帮你构造报文,这两个函数前缀都是一样的——guac_protocol_send_XXX,第一函数帮你构造一个name命令的报文,你只需要把参数填上去即可,如(假设我参数填了   aXXXX   ):

"4.name,5.aXXXX;"

第二个函数也类似,官方提供了很多这样的函数——guac_protocol_send_XXX,便于发送guacamole协议的报文,返回值为0代表成功,非0代表失败。这个函数不仅构造报文还顺便把报文发送了,这是第一个套接字参数的作用。

最后一个函数就是刷新缓冲区,把剩余所有未发送的报文都发送了。返回值,成功为正数,超时为0,错误为负数。

strlcat.c strlcpy.c strljoin.c

这三个文件一块讲了,每个文件对应于它文件名的一个函数。

size_t guac_strlcat(char* restrict dest, const char* restrict src, size_t n);
size_t guac_strlcpy(char* restrict dest, const char* restrict src, size_t n);
size_t guac_strljoin(char* restrict dest, const char* restrict const* elements,
        int nmemb, const char* restrict delim, size_t n);

第一个函数,拼接两个字符串,用法跟标准的拼接函数差不多,关键是第三参数,第三个参数说明第一个参数的长度,也就是目的串的大小(这个大小包含'\0'),如果长度太小就拼接一部分,比如

char buffer[1024];
strcpy(buffer, "Apache ");
guac_strlcat(buffer, "Guacamole", 9);
//结果拼接的结果是
//"Apache G"
//返回值为16

返回值是源字符串和目地字符串的长度相加(无论空间是否足够,不统计'\0')。判断串的长度是以'\0'为标记判断,不是字符串长度。

第二个函数,拷贝字符串,用法跟标准的拷贝函数差不多,第三个参数说明第一个参数的长度,跟上面一样,返回值是源字符串的长度,不统计\0'。

char buffer[1024];
memset(buffer, 0xFF, sizeof(buffer));
guac_strlcpy(buffer, "Guacamole", sizeof(buffer));
//buffer为"Guacamole"
//返回值为9

第三个函数是拼接多个字符串,前面两个参数就是目的串和拼接字符串数组,第三个参数是拼接几个字符串,第四个参数是拼接两个字符串中间加的东西,下面我加了一个空格,第五个参数就是第一个参数的长度,跟前面一样,返回值是拼接后的长度,不统计\0'。

const char* const apache_guacamole[] = { "Apache", "Guacamole" };
char buffer[1024];

memset(buffer, 0xFF, sizeof(buffer));
guac_strljoin(buffer, apache_guacamole, 2, " ", sizeof(buffer));
//拼接后buffer为"Apache Guacamole"
//返回值为16

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值