linux bash shell 像cmd.exe 一样的滚动补齐功能

有些情况下,比如我们遇到文件名含有一些字符不容易输入时就很着急了,这时候就需要让linux shell像windows cmd.exe 一样自动补全部的文件名,且可自动按顺序一个个滚动切换。方法如下: 在用户目录创建 ~/.inputrc (若不存在则自己创建) 文件里添加一行: 。 登出再登陆用户就可以了。 For more details see the READLINE section in man bash .

gdb 简记

常用命令如下:(详情可以用 help 命令查看) r (run, restart)  s (step into)  n (next state, step over) finish (step out)  q (quit)  p (print anything you want) l (list) b (breakpoint) #设置断点: (gdb) b fileName.c:lineNumber 或者 (gdb) b function u (until) #运行到指定行 call  #调用函数 set  #设置变量  set args #设置main 的输入参数 bt (backtrace)  #查看堆栈 x #examine memory, (gdb)/FMT ADDRESS […]

关于Apache httpd 的SSI和cgi使用和思考

因为在单片机上的web服务是使用删减版的httpd服务器,只保留最原始的扩展功能,SSI和CGI。无法像pc上的服务器可以使用php,jsp之类的引擎。 SSI主要是为了往网页里面插入实时的变量,CGI主要是处理客户端发送来的请求。这样即使是最古老的浏览器也不会有什么兼容性问题。 但是这样的做法的结果是服务端的编程变繁琐了。作为单片机这种嵌入式web应用,应该尽可能工作量放在客户端来完成,减少服务端的复杂度。而且不需要太考虑兼容古老的浏览器,因为落后的东西就应该被淘汰。 早期的浏览器作为通用的客户端只拥有简单的功能,比如实现get和post等几个方法。大量的跳转和内容生成是在服务端运行的,就造成服务器的负载较大。自从javascript成为浏览器端标准的脚本语言后,各种网站的内容交互方式就变得更加自由了。我这里感受最深的就是使用客户端脚本把动态网页的生成工作放在浏览器端来做,数据由ajax 单独请求更新。嵌入式web经常需要显示一些实时的数据,把单独的数据请求放在后台实时更新,然后由脚本把它填写至网页。不像早期的技术使用SSI,服务端需要检索整个网页的SSI tag,然后查找变量,将数据实时更新至网页,然后发送整张网页。可以想服务端的压力有多大。其实这种思维模式就像网站程序和网站数据分开放一个道理。好处多多! 因为用单片机的web服务器调试前端代码会比较繁琐,要转码要下载,频繁修改就不方便。所以直接在pc的web服务器上调试前端代码,并且使用SSI和CGI,模仿单片机C后台的动作,这里要有一些技巧。 在Apache httpd web服务器上使用SSI和cgi,可以参考服务器主页上的帮助文档 http://httpd.apache.org/docs/current/howto/ssi.html。这里简单做个记录。 SSI 按照官方介绍把SSI功能打开。怎么设置httpd.conf就不多说。这里简单记录下其使用规则。 想设置某个SSI tag时,可以使用 在需要调用它的地方使用 就可以显示出 xxxx 了。 仅仅是这样使用,跟我们在使用最原始的SSI还是有点不一样。 为了方便调试,我们可以在页面上头加上 重定义这个未找到SSI时的提示语言,原本的提示语言很长,不方便调试。 CGI有几个要点: 1. CGI开启后,默认设置ScriptAlias是只执行cgi-bin下的脚本。你可以将自己的web目录添加进去,因为实际请求的路径不一定是/cgi-bin。 2. 这里可以用perl、python或者bash脚本来模仿单片机c的后端应答动作。这样调试好前端代码后,下进单片机后再慢慢调试后端代码就方便了。注意在perl前面要设置好perl.exe的路径。同时可以修改.pl后缀为我们想要的.cgi它也可以得到执行。完美模仿单片机后端逻辑! Get!

总结几个C 语言比较高级的编写技巧

看了一些源代码,这里总结几个不常见的,但是比较好用的C 用法。也许这些功能在C++中有扩展,但是个人基本不用C++。其实这些应该是属于预处理器的功能。若是之前没有见过,遇到时会感觉云里雾里的。 直接定义字符串: 我们可以用#define 定义字符串常量,比如: #define HELLO   “hello” 这样就相当于是: char *HELLO= “hello”; 而且使用#define 来定义的好处是可以直接拼接字符串,这些应该都是由预处理器来帮我们处理的(没有仔细考证,但想像其中原理应该是这样)。比如: #define HELLO “hello” #define WORLD “world” puts( HELLO WORLD ); 定义内存池: 在嵌入式系统中一般不用内存堆的动态分配,因为容易产生内存碎片导致大块内存分配不到(可以用带小块内存合并功能内存管理方式),或者是会因为某个模块把内存堆耗尽了导致其它模块不能工作。通常会使用内存池的方式,而且每个软件模块有自己的不同大小固定数量内存池,这样可以做到每个模块内存互不干扰。说白一点就是一系列的分配好空间的数组。这可以参考lwip中内存池的分配。 #define LWIP_MEMPOOL(name,num,size,desc) u8_t memp_memory_ ## name ## _base [((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size)))];  

Http Authorization

Basic Authorization 从最初的基本的授权方式说起。 http头里添加:WWW-Authenticate: Basic realm=”xxx” 即可要求浏览器输入授权信息。 浏览器发送时会附带授权信息:Authorization:Basic YWRtaW46YWRtaW4= 它是由base64加密的。如上解密后为:admin:admin Basic authorization 的授权方式就是每个请求中在http头里都携带着base64加密的授权信息,服务器在每次收到请求时都要进行权限判断,再执行对应的操作。 由于考虑到授权,那自然涉及到了客户端状态。http  /0.9是无状态无连接的协议,一个特定的输入就对应一个特定的输出。由于http 不需要很强的实时性,属于一问一答的对话形式,且有时并发性强,不可能是一对一的专人(线程)负责一个会话。所以如果涉及到状态就不如把状态参数放置在请求中,服务端就要先对请求中携带的状态进行判断,再判断对应的操作是否有权限等等。按数字电路的理论,服务端的业务就变成两段式状态机的组合逻辑部分。状态部分可以保存在客户端或者服务端,这就变成了cookie和session了。 http /1.0增加了keep-alive 选项,http /1.1则默认了所有连接都有keep-alive选项。http keep-alive 选项就是说 发送完响应之后不服务端不主动关闭连接(http /0.9 是会主动关闭连接的)。http 的keep-alive 应该通过是tcp的keep-alive 定时心跳来维持的,不过http的keep-alive 还有一层意思是即使tcp 连接断开了,http的session还是keep alive的,http 可能也维护着一个保活定时器去试探每个连接上的客户端是否仍在线(这个不清楚)。 当http涉及到用户的概念时,就需要识别用户了,可能最早http识别一个客户端的方法跟标识一个tcp连接的方法是一样的,即IP+Port的形式来断定。然后变成 client 的(IP+Port+uid+password)的,也就是Basic Authorization的方式。状态信息可以放在url(GET),http header(authorizatin, cookie) 或者 post content里面。   对安全性的考虑: 由于每次都携带用户名和密码的这种请求方式极不安全,所以衍生版本就是用cookie来替代每次都携带的用户名和密码,这样就算cookie被人获取利用,也不会泄漏用户名和密码。只有在登陆的时候会传输一次用户名和密码。再者base64是可逆的加密方式,后面也使用不可逆的加密方式如md5(因为它是有损的加密,不可能还原出原密是什么)。但是如果被抓包,还是会被黑客冒名向服务器发出请求。所以早期网上支付等等就需要k宝,动态口令卡之类的东西。现在由于TLS/SSL等技术的出现,http on TLS/SSL 就很安全了。传输层或者socket层之上的信息全部使用密钥加双方证书加密,再靠抓包破解就很难了,所以这几年网络支付又火了起来。 PS: 看了一个wordpress登录的时候是直接POST 明文用户名加密码,好危险。   FAQ: Chrome delete authorization […]

ss安装笔记

现在的上网安全性越来越差了,感觉随时有人在监视你上网。电信送的政企网关更是漏洞百出,dns经常被劫持,而且电信留有后门,非常不安全。再加上之前出现的同事邮件被监视,诈骗邮件、短信等等的问题,公司的网络真的是问题很大。 之前部署的openvpn服务在手机端用,似乎dns有问题不能用,不用dns的服务则可正常使用。而PC端使用OpenVPN无任何问题。所以打算在国内的服务器上也部署一个SS来上网。 pip安装方式简单记录下: 由于在 pip install 的时候出了问题,估计是国内访问pypi资源很慢,安装失败。于是就打算使用源码安装方式。 1. 用scp 拷贝源码到服务器。 2. 要赶紧把ss的源码好好学学,不然哪天翻不出去也要会自力更生,嘿嘿。 特别 github 还有python大牛源码解析的版本和其它衍生版本可以下哦!这里不贴出来,以免被封。 tips: 对于长城宽带,ss代理若使用常用的443端口经常遇到出不去的情况,可以用telnet 通一下443端口,然后就神奇的可以出去了。这也是无意中发现的,长宽真是个神奇的存在!电信就很少遇到这个问题,不过有极少情况可能是因为找不到路由,可以tracert 一下服务器应该就能出去了。

ubuntu 上部署OpenVPN服务

缘起: 最近家里的长城宽带通往海外的线路堵得厉害(感觉长城宽带就是GFW的实验场),用ss翻墙都难连上服务器,apple store也难连上。于是不得不在国内阿里云的服务器上搭一个VPN。不仅可以解决长城宽带的问题,平时手机在外面连接不安全的wifi时也不用担心信息会泄漏了。另外VPN还可以将分布在各处的内网主机组成局域网,VPN服务就相当于是在中间的虚拟路由器。 参考了以上几个链接的博客总结一下安装过程。 http://www.linuxidc.com/Linux/2014-08/105925p2.htm http://www.linuxidc.com/Linux/2012-01/51702.htm https://help.ubuntu.com/lts/serverguide/openvpn.html http://blog.csdn.net/joyous/article/details/8034132 OpenVPN 是在TCP/UDP 端口上建立一个安全IP网络通道,支持SSL/TLS 对数据加密、授权等。简单点理解就是在传输层上建立一个虚拟线路,作IP包的交换,相当于一个虚拟网卡。原文是这么说的: * OpenVPN — An application to securely tunnel IP networks * over a single TCP/UDP port, with support for SSL/TLS-based * session authentication and key exchange, * packet encryption, packet authentication, and * packet compression. 一、安装OpenVPN dnsmasq 在用来在vpn路由器功能里面充当域名服务器的作用。有的版本openvpn包含了 easy-rsa ,不用再安装easy-rsa。如果没有再自行安装easy-rsa,它包含生成密钥用的脚本文件。 注:更新本地仓库:apt-get update 安装完查看openvpn相关安装包位置的命令: […]

Lwip 内存管理

Lwip 用它自己的动态内存分配方式替代了标准C的malloc(); 它可以使用MEM_POOL的方式分配内存,即开辟几个不同尺寸的缓冲池,给数据分配合适的缓冲区来存放,就类似于使用数组的方式,可能会比较浪费空间,但是可以有效避免内存碎片产生, 这在第二部分讲。两种方式分别在mem.c memp.c里面实现,下面先总结一般的内存堆分配方式。 (一) 内存堆动态分配方式 首先是内存对齐,这里用到的MCU是按4字节对齐的。这一语句功能是将addr 调整成最靠近addr的且能被4整除的值,其实就是(addr+3)&(~(u32)(0x03)),+3之后有余数的自然就进位了然后再舍掉余数。其实也可以用 addr = (addr&0x03)?(addr+1):addr; 这样应该也可以,更容易理解一些,但是没有上面的简便。 这里申请了一个内存堆ram_heap, 大小包括整个MEM_SIZE + 两个STRUCT_MEM的大小 + 4, 假设申请了MEM_SIZE 为8k。 内存初始化。ram 指向了ram_heap开头, 并且在开头初始化了一个struct mem。 ram_end 指向了MEM_SIZE之后的第一个STRUCT_MEM, 这里不知道是不是bug,我觉得应该指向&ram[MEM_SIZE_ALIGNED+SIZEOF_STRUCT_MEM]; 没时间了,以后再慢慢研究。 lfree最开始也指向了开头。 ->next 等这些参数都是相对地址,相对ram的,方便之后用数组的方式访问。 内存分配函数。首先对齐size,并且size不能太小或者太大,太小容易产生过多的碎片导致后期内存不足。 然后搜索heap,找到适合的块。lfree指向未分配的内存位置,刚开始它是在开头。 ptr=lfree-ram 即是lfree相对ram的位置,即已经用掉的内存大小。 ptr mem 先指向lfree所指的位置,当这块内存未被使用并且剩下的内存大于size时,…略复杂,待续… (二) 内存池的动态分配 内存池顾名思义就是一个个划分好的池子,不像内存堆一样东西乱堆。 pbuf是协议栈里最常用的数据类型,它有多种类型的存储方式,如下: 我们从pbuf入手研究一下MEM_POOL内存池的编写方式。 pbuf_alloc(PBUF_POOL)调用的是: p = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL); 我们来看看MEMP_PBUF_POOL是如何声明的: memp_std.h里定义了各种类型POOL. memp.c 定义了 几个数组来保存每个pool的元素大小和数量。定义一个memp_memory[]内存块保存所有的pool。 […]