duilib 消息自己简单总结

背景

最近由于各种原因又学习了duilib c/c++界面库

总结

  1. CWindowWnd::__WndPro
  2. pThis->HandleMessage
  3. m_PaintManager.MessageHandler(uMsg, wParam, lParam, lRes)[这个是最重要的]

前2步

调用虚函数 HandleMessage, 我们做界面开发时候会继承CWindowWnd其实前面2步,只是把窗口HWND 与 我们代码对象绑定起来,建立关系,duilib 提供 WindowImplBase 方便我们开发界面而已,我们也可以不继承这个类,自己写事件和一些事件处理。

m_PaintManager.MessageHandle

进入界面库核心逻辑,前面都是只是传统界面逻辑,这里根据windwos 系统消息[WM_PAINT, WM_LBUTTONDOWN] 等等事件。

  1. 属性【画图】
  2. 行为

画图

根据我们的节点,一个一个画出来,这个类似html技术,目前所有主流界面开发都有点类似html 界面开发思路。

行为

根据鼠标和按键触发对应行为,dulib的行为基本都是通过notify 时间投递,这个投递在当前HWND里面。

这个类似win32 界面开发, 传统win32开发增加一个按钮事件 ,那么就投递 BM_CLICK给父窗口,父窗口在消息处理函数中处理这个消息。

怎么找出服务器流量多的接口?

一、问题

最近发现服务器流量增加一倍,因为后台开发没有加日志,无法分析流量的走向,就算有日志,也无法很好发现流量的占比。

二、解决过程

  1. tcpdump 抓包,保存文件(如果windows直接用wireshark抓包即可)
  2. 用wireshark 统计模块,可以看各个接口占比和流量速度

三、缺点

因为https 证书问题,直接抓包无法解密HTTPS,但自己服务器,应该可以解密,这个百度一下wireshark 解密HTTPS 配置 应该就可以了。

android 协同逻辑之adb forward

一、背景

开源scrcpy 用adb forward 进行转发,这样子不用知道电脑的IP,直接给PC指定端口发送数据就会传送到手机端

二、问题

自己在开发自己协同工具的时候,发现虽然转发,但流量还是在手机显示,而用alink(基于开源的scrcpy开发),却没有显示流量。

三、解决过程

自己命令:

adb forward tcp:9990 tcp:9990

他们用的:

adb forward tcp:9990 localabstract:local

我发现他们用localServersocket而不是Sersocket,于是百度一下这种locaksocket可以设置别名,类似管道,不走协议栈,常用于IPC进程通信,所以没有显示流量。

四、展示我自己demo

用electron 显示,底层截图API,目前不是采用视频流,因为觉得以后用于远程时候,不需要视频流,截图就已经满足了。目前基本功能能用。

mysql 拿取随机数据思考

一、背景

自己因为有一个答题插件逻辑,需要从数据库随机选择一定数目的题目,这个业务已经被同事实现,但我觉得他实现不对或者不够好,于是思考这个问题。他用rand() 产生一个随机数,然后大于这个随机数 加上limit 得到 题库。

二、问题

  1. 题库是连续的,用户体验不好
  2. 随机概率增大,如果用这个思路写抽奖那么绝对是不对的。

三、解决思路

假设我们选择uid 用户的ID 是整数,主键。。

select * from xxx where uid >= (rand(max(uid) – min(uid) ) + min(uid)) limit 1

上面手写,不代表语法正确, rand 只是找一个随机数据, 这个可以程序传过来,不一定要数据库随机数。 后面+min(uid) 只是为了防止随机到0而已,保证uid最小值而已。

如果要随机多条,应该调用多次,而不是limit 10 (假设多条是10),因为这里有一个隐藏前提,随机条数和数据必须差别比较大,不然很可能出现连续,而不是看起来随机的。

四、补充

select * from xxx where uid >= (rand(max(uid) – min(uid) ) + min(uid)) limit 1

select * 加了条件,如果数据库有10条数据,uid(0~9),如果我随机5条数据话,如果用上面的 select * from xxx where uid >= (rand(max(uid) – min(uid) ) + min(uid)) limit 5 。很容易出现连续的,而且数据缺失。select * 拿数据,会一行行拿,条件对比,而不是扑通一下拿取所有数据,然后才进行对比,所以用rand() limit 个数,会出现不连续,而你自己用 select * from xxx where uid >= 10 limit 5 却是 连续的,这里10我只是随便举一个数字而已。 如果数据少,加上UID自增,随机到大于5是50% ,如果我选择5条数据,那么很容易不够,并且连续,这里连续满足where条件太少了,所以导致连续,如果数据足够多就没有这个问题。

我以前全表扫描比较慢,测试200W数据,个人电脑也就0.85秒消耗。如果加上条件那么速度快很多,更不要说有索引的情况下。。。

这个问题我记录下来,只是跟后端开发探讨出来,自己不喜欢写数据库东西。只是记录技术而已。

node request 设置代理

一、背景

自己用node request 请求 http 发现请求无法正确应答,我用fidder抓包没有抓对应数据包,因为默认node 不会走 windows 默认代理。

二、解决过程

在request 构建增加参数 proxy: ‘http://127.0.0.1:8888′

这个设置代理到fidder里面去,如果非HTTPS 可以直接用wireshark来抓包。

三、补充

如果是第三方程序,如果不会默认走代理,可以用proxifier, 这个软件出来很多年,自己可以百度下载,官方可以试用30天。

proxifier过滤指定进程名字,然后转发443 80 端口数据包到fiddler上面,这样子就可以抓任何程序的包,无论他支不支持代理。

edge微软账号登录

一,问题

edge 虽然可以同步登录,但大多数会出现登录出现问题,我以前都是通过梯子登录,最近发现一个简单方法解决了,自己记录一下。

二,解决

通过填写微软的dns就可以加快登录过程。4.2.2.1 4.2.2.2 这个地址

登录后可以改回自己默认DNS,只是临时切换一下,而可以用网上快速切换DNS的工具,进行快速切换。

vs 运行库知识点

一、问题

  • 我们编译c/c++的执行程序(exe),如果运行库没有选择静态编译(mt),那么可能在别的电脑上就无法运行(因为没有对应的运行库)
  • 程序选择mt静态遍历,我们链接别的第三库会出现链接报错

上面是我们用c/c++编译经常遇到问题。

二、运行具体文件的作用[vs2019为例子]

  • vcruntime140: c语言运行库,比喻我们用到prinf
  • msvcp140.dll c++ 运行库 ,比喻我们用到的 std::cout
  • 其他补充,以前的版本不一定有,有可能是win10才有

140 代表是运行库的版本号,你用的vs版本不一样,这里数字不一样。

三、解释

1:问题1解决办法

  • exe 运行库选择mt,这个在vs 工程选项 c/c++ 运行库进行设置
  • 安装包写脚本自动检测,安装对应的运行库程序【用的不少,但国内版本比较多,不一定能安装成功】
  • 自己直接在exe运行库放 所有运行库,直接从vs 目录找到对应的版本运行库就可以了【这种比较多】

2:问题2解决办法

如果你exe选择静态遍历,第三方库选择md 动态编译,链接时候会发现运行库的代码已经实现,出现冲突,相当于定义出现2次了,导致无法链接。【凭记忆写的,改天自己用一个第三方库验证一下】

第三方库也选择静态编译就不会冲突了,但实际中非常麻烦,这个c/c++ 非常不方便地方,跟现在高级语言比起来麻烦很多,导致新手门槛太高。我自己都不怎么用c/c++写一些工具,用别的高级语言,直接几行命令就可以继承第三方的库直接开始工作,c/c++还需要单独编译,单独编译还不一定能成功。

四、总结

本篇文章只是为了记录一下,因为前段时间正好思考这个问题,到底他们运行库怎么搞的,为什么会编译出错等等。有些问题不思考,不验证还真不知道具体原因,只知道那样子操作就可以,但具体为什么却不知道

大小端理解

一、背景

这块知识点算是比较常见,我们传送网络二进制自定义协议一定会遇到的,我最近看到一个问题,于是我思考为什么会有大小端的问题,他到底是哪一层导致的。基本知识我这里就不说了,自己搜索一下就能知道

二、思考

我们看的书籍或者网络的文章都说大小端跟CPU有关系,但跟高级语言没有关系,我们用c/c++,c#的时候我们赋值给变量根本不关心大小端,比喻 short i = 0x1234 我们根本不用关心他在内存里面是大端还是小端,因为他的值就是0x1234。不用关心他的内存形式。

另外一个知识点,i = a + b; 如果a 和 b 如果在别的线程可能被修改,那么这样行代码是非线程安全的,那为什么会线程不安全, 因为 i = a + b 在汇编层是多行代码,并不是一行代码,所以高级语言的线程安全,不能只看高级语言层线程安全,单行操作代码也可能是非线程安全的。【这里举例不是非常好,如果以后能想到更合适才写吧】

我们知道cpu 没有变量概念,只认识0 和 1 ,高级语言不关心内存的形态,那么可以断定大小端只是汇编层问题,我们知道汇编 命令 + 操作数, 那么32 位中 操作可以word 也可以是dword ,汇编是跟cpu最直接的,所以厂商不一样,操作数在内存形式不一样,所以才出现大小端的问题。所以问题是在汇编层导致。

三、补充

自己google了一下也没有找到任何英文文档来证明我上概念。

win11 关闭蓝屏 重启不蓝屏

一、背景

蓝屏是ndis.sys 导致的蓝屏,基本百度或者google也找不到解决办法,说明自己这个问题很大可能第三方程序导致的问题。

二、排错

  1. 通过日志查看到生成dump文件所在路径。(右键我的电脑,点击管理,找到window的日志)
  2. 用windbg priview 查看dunmp文件(应用商店可以下载)
  3. 看到回调过程
  4. 找到一个Neo_VPN.sys 调用
  5. 通过搜索在C:\Windows\System32\Drivers\Neo_VPN.sys

三、解决方案

  1. 进入win11 安全模式
  2. 删除 C:\Windows\System32\Drivers\Neo_VPN.sys
  3. 重启电脑,正常

四、总结

每个蓝屏不一定相同,但基本按照上面流程一般能找到由于那个驱动导致蓝屏,删除对应的蓝屏基本就能解决。我自己这个驱动是很多年前安装一个客户端,但卸载了,驱动没有卸载,导致升级win11造成不兼容

java 压缩的二进制数据传递给node js处理问题

一, 背景

自己压缩android 截图数据压缩然后网络传递给我node程序,然后发现node 无法解压。

二,排错过程

打印java 压缩的二进制数据数组,打印node收到 buffer,发送java数组函数负数,而node 得到没有负数

三,思考

看到这个2边数据不一样,我就想起来是什么导致。java byte 是 -128~127,node byte是 0~255. 这样子导致数据对不上,我要说一点二进制数据是一样的。这个只是node 读同样的二进制,解析数据0~255范围[byte],java虚拟机解析~128-127。这个就跟我们传送数据,会出现大端和小端问题一样,必须保证2边一致。。。。

四,解决

我直接在NODE 处理每个字节 var c = buffer[i] & 0xff 即可