aardio封装库) sunny抓包工具的使用

这篇具有很好参考价值的文章主要介绍了aardio封装库) sunny抓包工具的使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

还有个迭代器,基础语法基本已经说完了,后面想到啥再补充,之后的教程会从以下方面来讲:

  • 基础库的使用,比如string、table等
  • 基础控件的使用,比如listview、tab等
  • aardio和Python交互,比如给Python写个界面
  • 自带的范例程序
  • 我写的一些小程序

当然,我的理解也是很基础的,特别是在界面设计上,我都是用的默认控件的默认设置,不会去自定义控件内容。要想做出特别炫酷的程序,你还得依赖其他语言和工具的基础。例如用HTML和CSS来实现界面。

元表、元方法

参考文档:

  • https://bbs.aardio.com/doc/reference/libraries/kernel/table/meta.html
  • https://bbs.aardio.com/doc/reference/the%20language/operator/overloading.html

主要是用于重载运算符和内置函数的行为。

表可以定义另一个表作为元表,然后在元表里定义元方法来定义操作符或内置函数操作表的一些行为。这种类似于Python的魔法方法,在Python中使用__eq__定义==的行为,而在aardio中用_eq元方法来定义==的行为。

初级使用例子

举个例子,python中print会调用对象的__str____repr__来打印一个对象,而aardio也是调用tostring来打印一个对象,但表默认并没有定义_tostring元方法,导致打印出来的内容是table: 03B2E3A8的格式

我们可以通过给表定义_tostring元方法,来使io.print或者console.log正常显示表

import console; 
io.open()
var tab = {
	a=1;
	b=2;
	@{
		_tostring = function(...) {
		    // 元方法里不能调用触发元方法的函数,比如_tostring里不能调用tostring
		    // _get元方法可以通过[[k]]运算符来避开元方法,通过.和[]会触发_get,而[[]]不会
			return table.tostring(owner);
		}
	}
}
io.print("没有定义元方法" , {});
io.print("定义了元方法" , tab);
console.pause(true);

输出如下:

没有定义元方法  table: 03A8E2F8
定义了元方法    {
a=1;
b=2
}

运算符重载

这个就不细说了,应该很容易理解。

io.open(); tab = { x=10 ; y=20 };
tab2 = { x=12 ; y=22 }
//c = tab + tab2; //这样肯定会出错,因为 table默认是不能相加的

//创建一个元素,元表中的__add函数重载加运算符。
tab@ = {
	_add = function(b) { 
		return owner.x + b.x
	};
}

c = tab + tab2; //这时候会调用重载的操作符 tab@._add(tab2)
io.print( c ) //显示22

入门使用例子

还有一个很常用的元方法是_get_set,是定义访问对象属性时触发的。利用这个可以让代码量少很多,看起来逻辑也更清晰。

这里举个实际例子,我在封装sunny的时候,遇到个很累人的事。sunny的dll导出函数,返回值有些是指针,你需要手动给他转成字符串,而且还需要手动释放这个指针指向的内存,也就是说你调用一次导出函数,就得写至少三行代码(调用、转字符串和释放)。

那么,有没有一种方法,定义完这个导出函数,在使用的时候就调用函数释放内存,并转成字符串返回,而不用我每次都手动释放和转字符串。

先定义request类,现在只需要给它定义一个messageId属性和_meta元方法:

namespace sunny;

class request{
	ctor(messageId){
		this.messageId = messageId;
	}
	@_meta;
	
}

@后面跟的是元表的名称,你可以将元表定义在名字空间里,这样看起来代码更舒服。下面在类的名字空间里定义dll方法和元表.

namespace request{
    //释放指针的函数
	Free = ::SunnyDLL.api("Free","void(pointer p)");
	// 下面的函数第一个参数都是messageId
    DelRequestHeader = ::SunnyDLL.api("DelRequestHeader","void(int id,str h)");
    GetRequestBodyLen = ::SunnyDLL.api("GetRequestBodyLen","int(int id)");
	GetRequestBody = ::SunnyDLL.api("GetRequestBody","pointer(int id)");
	// 定义一个中间方法
    // name是要调用的导出函数,messageId则是导出函数的第一个参数
	xcall = function(name, messageId, len){
		var func = self[name];
		if(!func) error("不支持的函数!");
		function proxyFunc(...){
			var v = func(messageId, ...);
			var result;
			if(type(v) == type.pointer){
				if(len) result = ..raw.tostring(v,1,len);
				else result = ..raw.tostring(v);
				Free(v);
			}else{
				result = v;
			}
			return result;
		}
		
		return proxyFunc;
	}
	// 定义元表
	_meta = {
		_get = function(k){
			return xcall(k, owner.messageId);
		}
		
	}
}

这个代码初看可能有点费劲,我们拆解着来看。

首先前面几行只是定义了四个dll的导出函数,然后下面定义了_meta这个表。

而_meta里只定义了一个元方法_get,它的作用是当你访问对象的属性时会触发这个方法,然后给你返回值。比如我先实例化一个request对象

r = request(111111);
// 当访问r.GetRequestBody时,这个对象没有GetRequestBody属性,所以会触发_get元方法
// 得到的返回值就是 返回它的返回值也就是`xcall("GetRequestBody", owner.messageId)`.
console.log(r.GetRequestBody)

这里的owner就是指r这个对象。然后定义了xcall这个函数,它里面又定义了一个函数proxyFunc,并将它作为返回值,这种被称为闭包。先分析下xcall方法

// 这里的self指的是当前名字空间,也就是request,name则是需要调用的方法名,例如是GetRequestBody
// 这里func的值就等于GetRequestBody,也就是::SunnyDLL.api("GetRequestBody","pointer(int id)");
var func = self[name];
// 如果func是null的话,说明当前名字空间下没有这个函数,也就不是我们定义的sunny导出函数
if(!func) error("不支持的函数!");
// 定义了proxyFunc函数,`xcall(k, owner.messageId)`返回的值就是proxyFunc函数,这里的三个点表示传入任意个参数,类似于Python中的*args
function proxyFunc(...){
    // 调用GetRequestBody(messageId, ...)
	var v = func(messageId, ...);
	// 定义返回结果
	var result;
	// 如果结果是指针的话
	if(type(v) == type.pointer){
	    // 就把它转为字符串,二进制数据需要指定长度,不然就是到\0结束
		if(len) result = ..raw.tostring(v,1,len);
		else result = ..raw.tostring(v);
		// 调用导出函数释放内存
		Free(v);
	}else{
	    // 如果是其他类型数据就直接返回,比如数值或null
		result = v;
	}
	return result;
}

这样一番折腾,起了什么效果呢,看一下下面两段代码,如果不利用元方法的话,你使用dll导出函数得这么写

// 导入request名字空间
improt request;
// 调用名字空间下的函数
var messageId = 111111
var pResult = request.GetRequestBody(messageId);
// 将指针转为字符串
var result = raw.tostring(pResult,1);
// 释放内存
request.Free(pResult);
// 再使用其他导出函数也需要重复写这几行代码

看着就几行代码,但是你想想调用一个函数都得写好几行,如果调用多次呢。而定义了xcall和_meta之后,只需要这样写代码:

improt request;
var messageId = 111111;
var req = request(messageId);
var result = req.GetRequestBody();
// 后面调用都只需要用req.方法名()调用,不需要管raw.tostring和Free了

因为req是可以复用的,所以我调用任何导出函数都只需要写一行代码,使用sunny库的代码也变得更简洁易懂了。

官方例子

给表创建一个代理,监控表属性的访问和设置:

// 创建一个代理,为另一个table对象创建一个替身以监控对这个对象的访问
function table.createProxy(tab) {
    var real = tab;//在闭包中保存被代理的数据表tab
    var _meta = {
        _get = function(k){
            io.print(k+"被读了");
            return real[k];
        };
        _set = function (k,v){
            io.print(k+"被修改值为"+v)
            real[k]=v; //删除这句代码就创建了一个只读表
        }
    }
    var proxy = {@_meta};//创建一个代理表
    
    return proxy; //你要访问真正的表?先问过我吧,我是他的经纪人!!!
}

//下面是使用示例

tab = {x=12;y=15};
proxy = table.createProxy(tab);//创建一个代理表,以管理对tab的存取访问

io.open();
c = proxy.x; //显示 "x被读了"
proxy.y = 19; //显示 "y被修改值为19"
io.print(proxy.y); //显示 "y被读了" 然后显示19

所有的元方法

元方法/属性 函数定义 Python中的魔法方法 说明
_weak 用不到
_type 属性 type(obj)函数的行为
_readonly 属性 等于false,_开头的成员也不是只读属性
_defined 感觉没啥用
_keys 属性 可用于table.keys等函数动态获取对象的键名列表(例如动态生成键值对的外部JS对象可使用这个元方法返回成员名字列表
_startIndex 属性 用于table.eachIndex等函数动态指定数组的开始下标。
_get function(k,ownerCall) __getattr____getitem__ 如果读取表中不存在的键会触发_get元方法并返回值
_set function(k,v) __setattr____setitem__ 当你给表的一个缺少的键赋值时会触发_set元方法
_tostring function(...) __str____repr__ tostring(obj, ...)
_tonumber function() tonumber(obj)
_json function() web.json.stringify(obj),可返回一个可被转化为json的值。或者返回一个字符串和true
_toComObject 用于自定义一个表对象如何转换为 COM 对象,可定义为函数,也可以直接定义为对象
_eq function(b) __eq____ne__ ==!=,比较对象时,两个对象的_eq必须是同一个
_le function(b) __le____ge__ <=>=
_lt function(b) __lt____gt__ <>
_add function(b) __add__ +
_sub function(b) __sub__ -
_mul function(b) __mul__ *
_div function(b) __truediv__ /
_lshift function(b) __lshift__ << 左移
_rshift function(b) __rshift__ >> 右移
_mod function(b) __mod__ % 取模
_pow function(b) __pow__ **幂运算
_unm function() __neg__ - 负号
_len function() __len__ #取长运算符,Python中则为len函数
_concat function(b) ++ 连接运算符
_call function(...) __call__ 对象当函数来调用

属性元表

不仅可以给对象定义元表,也可以给对象的属性定义一个元表,有点类似于Python中的property,可以控制属性修改和获取的行为。

如果要看例子的话,可以在aardio的目录全局搜下@_metaProperty

以使用最多的属性text为例,基本每个控件都有一个text属性,你可以很方便的通过.text获取和修改空间显示的文字。

其实不用属性元表也能实现这个效果,代码如下:

import console; 
class staticText{
	getText = function(){
		..console.log("获取到界面文本内容")
	};
	setText = function(v){
		..console.log("将文本("+v+")显示到界面控件上")
	}
	@_meta;
}

namespace staticText{
    _meta = {
        _get = function(k){
        	if(k == "text"){
        	    return owner.getText();
        	}
        };
        _set = function(k,v){
        	if(k == "text"){
        	    return owner.setText(v);
        	}
        }    
    }
}

s = staticText()
console.log(s.text);
s.text = "修改文本";
console.pause(true);

但是如果属性多了的话,就需要一堆的if来判断属性,所以aardio作者就引入了metaProperty这个功能。这样写的代码看起来更简洁和清晰,用法如下:

import console; 
import util.metaProperty;

class staticText{
	getText = function(){
		..console.log("获取到界面文本内容")
	};
	setText = function(v){
		..console.log("将文本("+v+")显示到界面控件上")
	}
	@_metaProperty;
}

namespace staticText{
    _metaProperty = ..util.metaProperty(
        text = {
            _get = function(){
            	return owner.getText();
            };
            _set = function(v){
            	return owner.setText(v);
            }
        };
        // 可以写其他属性
    );
    // 可以打印下_metaProperty看看
    ..console.dump(_metaProperty);
}

s = staticText()
console.log(s.text);
s.text = "修改文本";
console.pause(true);

本文由博客一文多发平台 OpenWrite 发布!文章来源地址https://www.toymoban.com/news/detail-843147.html

到了这里,关于aardio封装库) sunny抓包工具的使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Http协议①】认识http协议,学会使用fiddler抓包工具进行抓包.

    前言: 大家好,我是 良辰丫 ,今天我们一起来学习http协议,http协议是应用层的协议,应用层是最接近程序员的,那么,http协议到底是什么呢?我们往下看.💞💞 🧑个人主页:良辰针不戳 📖所属专栏:javaEE初阶 🍎励志语句:生活也许会让我们遍体鳞伤,但最终这些伤口会成为我们

    2024年02月05日
    浏览(48)
  • Fiddler抓包工具配置+Jmeter基本使用

    一、Fiddler抓包工具的配置和使用 在编写网关自动化脚本之前,得先学会如何抓包,这里以Fiddler为例。会抓包的同学可以跳过这一步,当然看看也是没坏处的…… 局域网络配置     将要进行抓包的手机与电脑连入同一局域网,电脑才能够抓到手机APP的请求,这里介绍一种我

    2024年02月07日
    浏览(45)
  • wireshark网络抓包工具基础使用教程

    目录  简介 WireShark软件安装 Wireshark 开始抓包示例 Wireshark过滤器设置 停止抓包 ​编辑保存数据 界面介绍 基础操作 1. 调整界面大小 2. 设置显示列 1)添加显示列 ​2)隐藏显示列 3)删除显示列 3. 设置时间 ​4. 标记数据包 5. 导出数据包 6. 开启混杂模式 WireShark是非常流行的

    2024年02月16日
    浏览(48)
  • 【保姆级教学】抓包工具Wireshark使用教程

    今天讲一下另一款底层抓包软件,之前写过两篇抓包软件 分别是 fiddler抓包【https://www.cnblogs.com/zichliang/p/16067941.html】 mitmdump抓包【https://www.cnblogs.com/zichliang/p/16067941.html】 Wireshark (前身 Ethereal) 是一个网络包分析工具该工具主要是用来捕获网络数据包,并自动解析数据包为用户

    2024年02月08日
    浏览(49)
  • Fiddler 抓包工具下载安装基本使用(详)

             在做软件测试或者Bug定位的时候会用到一些抓包工具,当然抓包工具还要一些其他用途可以做一些API的抓取,那么本篇内容就来讲 Fiddler 抓包工具的下载安装以及如何来实际的应用。讲了这些可能有的读者还不知道这个\\\"Fiddler\\\"怎么读呢?读 \\\"非的了\\\" 。那下面先来了

    2024年02月05日
    浏览(56)
  • 路由器抓包工具TCPDUMP使用方式

    tcpdump,用简单的语言概括就是dump the traffic on a network,是一个运行在linux平台可以根据使用者需求对网络上传输的数据包进行捕获的抓包工具,windows平台有sniffer等工具,tcpdump可以将网络中传输的数据包的\\\"包头\\\"全部捕获并进行分析,其支持网络层、特定的传输协议、数据发送

    2024年02月08日
    浏览(40)
  • 【网络】抓包工具Wireshark下载安装和基本使用教程

    🦄 个人主页——🎐开着拖拉机回家_Linux,大数据运维-CSDN博客 🎐✨🍁 🪁🍁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬请批评指正!🍁🐥 🪁🍁🪁🍁🪁🍁🪁🍁 🪁🍁🪁🍁🪁🍁🪁 🪁🍁🪁🍁🪁🍁🪁🍁🪁🍁🪁🍁 感谢点赞和关注 ,每天进步一点点!加油

    2024年02月08日
    浏览(48)
  • 使用burpsuite抓包 + sql工具注入 dvwa初级靶场

    记录一下自己重新开始学习web安全之路②。 1.工具准备 sqlmap + burpsuite 2.浏览器准备 火狐浏览器 + 设置代理。 首先,先设置一下火狐浏览器的代理 http代理地址为127.0.0.0.1 ,端口为8080 3.burpsuite 准备 将burpsuite的抓包功能打开。 注:burpsuite 不抓127.0.0.1 /dvwa-master的包,所以需要

    2024年02月07日
    浏览(42)
  • 【JavaEE】HTTP协议和抓包工具的使用

    目录 1、HTTP的概述和抓包工具的使用 1.1、HTTP是什么 1.2、了解HTTP协议的工作过程 1.3、抓包工具的使用  1.3.1、抓包工具在HTTP传输时的工作原理  1.3.2、Fiddler抓包工具的下载和使用 2、HTTP协议格式 2.1、HTTP 请求格式 2.1.1.基本格式 2.1.2、了解HTTP请求包中的首行 🍂、认识URL 

    2024年02月15日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包