debian在window下的简单安装方法

下载win32-loader.exe,按照下一步定制自己的debian。

http://ftp.debian.org/debian/tools/win32-loader/stable/win32-loader.exe

Posted by imouse 2013年9月18日 17:48


A* 算法实现

https://github.com/imousewyfzml/mylibrary/blob/master/algorithm/AStar/myaStar.cpp

为了使用最大堆采用了multimap,并使用boost::lambda删除最大堆中value对应的key-value键值对.

可以读取map.txt地图,并将结果输出到map_res.txt.

Posted by imouse 2012年12月23日 01:27


如何删除git submodule子项

1. 编辑.gitmodules,删除对应要删除的submodule的行.

2. 编辑.git/config,删除有对应要删除的submodule的行.

3. 删除命令:

    git rm --cached bundle/xxxx  (PS:此处最后没有符号 / .)

4. 删除对应的目录:

    rm -rf bundle/xxxx

Posted by imouse 2012年11月11日 03:29


wxPython-国际化设置

    得益于gettext的支持,wxpython可以使用gettext库来让你的应用程序支持多国语,走向世界.在wxpython中有个比较方便的脚本mki18n.py,来自动生成.po和.mo.下面是一个自动生成的脚本:

gen_lang.sh放在你工程目录的lang或languages目录下,注意:这里生成的message.pot中的CHARSET已经要替换掉,否则程序无法执行,例如,替换成"UTF-8".

#!/bin/bash
# mki18n.py依赖app.fil,里面是所有的py文件列表
find ../ -iname "*.py" -print >app.fil
# 生成.po文件,domain一定要换成自己的
python mki18n.py -v -p --domain=your_application_name ./
# 上句命令,会生成message.pot文件,这个是一个模板文件.
# 如果需要zh_CN的翻译,可以拷贝message.pot为 your_applaciton_name_zh_CN.po
# 那么每次执行后就会生成your_applaciton_name_zh_CN.po.new,比较一下,合入新的未翻译的条目吧.

# 生成.mo文件
# 这个会生成类似
# zh_CN/LC_MESSAGES/your_applaction_name.po
python mki18n.py -m -e -v --domain=your_application_name --moTarget=./

     在应用程序中,你只需要调用下面的install函数即可.

# coding: utf-8
import gettext


def install(localdir, lang):
    gettext.translation("sgsgame", localedir=localdir, languages=lang).install(True)

例如:

# languages install
import util
langdir = os.path.join(home, "lang")
try:
    util.i18n.install(langdir, ['zh_CN'])
except:
    traceback.print_exc()
    util.i18n.install(langdir, ['en_US'])

然后,应用程序中,所有 _()包括的字符串都会被翻译成中文,当然,前提是你已经在po文件中翻译好了.

参考连接: http://wiki.wxpython.org/Internationalization

Posted by imouse 2012年10月28日 01:51


Kernel中timer错误使用触发了BUG_ON

    最近,AP终端老是重启,原因是timer中的cascade的BUG_ON语句被触发,这句BUG_ON的意思是检测挂在当前base数组中的timer,其结构中指向的base指针不是当前数组.按正常cascade,每次定时器因时间流逝,应该在切换base组的时候也切换自己内部的指针.这个base指针什么时候被改掉的呢?

static int cascade(struct tvec_base *base, struct tvec *tv, int index)
{
	/* cascade all the timers from tv up one level */
	struct timer_list *timer, *tmp;
	struct list_head tv_list;

	list_replace_init(tv->vec + index, &tv_list);

	/*
	 * We are removing _all_ timers from the list, so we
	 * don't have to detach them individually.
	 */
	list_for_each_entry_safe(timer, tmp, &tv_list, entry) {
		BUG_ON(tbase_get_base(timer->base) != base);
		internal_add_timer(base, timer);
	}

	return index;
}

     关于内核timer的使用,还要提到四个重要的接口:

     add_timer, mod_timer, del_timer,init_timer.

     函数名称已经很好的解释了函数的用法, 其中add_timer其实就是调用mod_timer,而mod_timer其实内部都调用了__mod_timer,那么__mode_timer做了那些事情呢?内核对mod_timer的注释说明了一切:

/**
 * mod_timer - modify a timer's timeout
 * @timer: the timer to be modified
 * @expires: new timeout in jiffies
 *
 * mod_timer() is a more efficient way to update the expire field of an
 * active timer (if the timer is inactive it will be activated)
 *
 * mod_timer(timer, expires) is equivalent to:
 *
 *     del_timer(timer); timer->expires = expires; add_timer(timer);
 *
 * Note that if there are multiple unserialized concurrent users of the
 * same timer, then mod_timer() is the only safe way to modify the timeout,
 * since add_timer() cannot modify an already running timer.
 *
 * The function returns whether it has modified a pending timer or not.
 * (ie. mod_timer() of an inactive timer returns 0, mod_timer() of an
 * active timer returns 1.)
 */

     可见,Init_timer后可以直接调用mod_timer来启动定时器.也可以在超时函数中调用mod_timer,以便形成周期定时器.del_timer用在模块退出或业务逻辑结束时,删除timer.

      在Init_timer中,会对base重新赋值.代码如下:

static void __init_timer(struct timer_list *timer,
			 const char *name,
			 struct lock_class_key *key)
{
	timer->entry.next = NULL;
	timer->base = __raw_get_cpu_var(tvec_bases);
	timer->slack = -1;
#ifdef CONFIG_TIMER_STATS
	timer->start_site = NULL;
	timer->start_pid = -1;
	memset(timer->start_comm, 0, TASK_COMM_LEN);
#endif
	lockdep_init_map(&timer->lockdep_map, name, key, 0);
}

     排查代码发现应用程序可能调用ioctl的时候,内核中初始化了两次timer,导致正在运行的timer->base被修改.准确的说是我们使用timer的方法不正确.

    1. init_timer尽量放在module初始化中

    2. mod_timer在适当的时候调用,以便启动定时器.

    3. del_timer在module退出或业务流程走完后删除.

    另外,timer中BUG_ON也可能是SMP的硬件问题,具体可yahoo关键字"bug_on panic in cascade in timer.c"

Posted by imouse 2012年10月27日 03:23


网站备忘

Posted by imouse 2012年10月26日 04:02


wxPython-在主界面上放点东西

     今天在主界面上放张风景图片吧,记得在学校上VC课程的时候,我们很喜欢把主窗体的背景搞的很漂亮,但是里面功能实现嘛,确实不敢恭维.能把图片放上面也算学到一些,先看wxPython怎么做到吧:

 

Posted by imouse 2012年10月22日 02:24


参与开源软件开发

    使用linux近8年时光了,我从开源社区学到很多知识,从学会安装linux,到使用各种软件,从事linux应用软件开发,再到linux内核驱动.不仅是在学校,还是在工作中,开源社区对我帮助很大,感谢那些无私分享代码的牛人,但我却一直因生活奔波没有时间去回馈社区.<做一名开源社区的扫地僧>给我不少的启发,选择一个项目,参与进去,才能真正感受开源带来的财富,不管是物质还是精神层面上的.不管怎样,Just do it.

Posted by imouse 2012年10月20日 00:02


使用NAT共享上网

      家里有一个台式机,但是没有无线网卡,必须使用网线连接路由器,但路由器在客厅,扯很长的网线很不方便.不过,我还有一台笔记本,上面装的是LINUX,所以想办法让台式机通过笔记本的eth口访问网络,那么就需要在笔记本上搭建一个NAT转发.

     在linux上,使用IPtables轻松搞定这一切.组网图大致如下:

第一种方法:

    IPtable设置如下:

# all interface 
export WAN=wlan0
# 获取无线网口的IP地址
export WAN_IP=`ifconfig ${WAN} | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}'`
export LAN=eth0
# 获取路由器的地址
export REAL_GW=`route | grep default | awk '{print $2}'`

# remove all 
# 清除NAT中的所有规则
iptables -t nat -F

# NAT settings
# 因为台式机(window)中的GW设置的是10.121.36.1,所以从笔记本上看LAN口收上来的包都是到10.121.36.1的,
# 这里就需要DNAT生效了,本质上是把数据包的目的地址给改掉,然后进入路由系统查找出端口
# 那么,下面这句话就是把去10.121.36.1的数据包,修改成${REAL_GW},这里是192.168.1.1
# 原有数据包头: 
# SRC: 10.121.36.89  DST: 10.121.36.1
iptables -t nat -A PREROUTING -i ${LAN} -d 10.121.36.1 -j DNAT --to ${REAL_GW}
# 经过上面一句话后,变成
# SRC: 10.121.36.89 DST:192.168.1.1

# 然后,进入route table,找出端口,在笔记本(linux)上,192.168.1.1是default gateway.且是wlan0
# 所以数据包从wlan0走.
# 数据包终归要有ACK,如果192.168.1.1回应10.121.36.89这个地址的话,将找不到路由而在路由器上丢弃.
# 那么下面这句话,将源地址修改${WAN_IP},这里是192.168.1.4
iptables -t nat -A POSTROUTING -o ${WAN} -s 10.121.36.0/24 -j SNAT --to ${WAN_IP}
# 最终,出wlan0的数据包就是:
# SRC: 192.168.1.4 DST: 192.168.1.1

数据包从wlan口回来的时候就执行反操作.把数据发送给台式机(windows).

OK,一切正常.我不需要更复杂的设置了,如果大家有兴趣,请参考<更安全的linux网络>这本书.

第二种方法:

iptables -t nat -A POSTROUTING -s 10.121.36.0/24 -j MASQUERADE

网友依云http://lilydjwg.is-programmer.com/提供.
 

快速参考:

刘苏平的博客 http://www.liusuping.com/ubuntu-linux/iptables-firewall-setting.html

Posted by imouse 2012年10月13日 22:15


IPSec简介

介绍


    IPsec是一种虚拟网络的应用,可以将internet虚成企业网来用,比如,公司在上海和北京都有办公区,两边为了能互相访问方便,一种解决方法是租用一条专用路线,物理上保证带宽和传输安全性,但是这样造价很高,有了VPN可以在inetenet上做一个逻辑层面上的网络,数据在彼此交换都使用AH或ESP方式对IP头部/载荷进行加密认证.这样保证了传输的安全性,但带宽就不好保证了, 总体来说VPN是较好的解决方案,节省成本.

工作模式


    IpSec工作在两种模式下:传输模式, 隧道模式.区别与隧道模式,传输模式对IP头部不再次封装,而隧道模式会根据配置规则把原始数据包封装到一个新的IP数据包中.


加密方式


    IPsec支持AH/ESP两种加密方式.
    严格的来说, AH不是一种加密方式,而是对数据的校验或称数字签名.校验范围如下:

    +------------+-----------+------------+
    | ip header  | AH header | ip payload |
    +------------+-----------+------------+
    | ------- verify scope ---------------|
   
    发送过程中,增加一个AH头部,使用hash算法将IP头部+IP数据区进行校验生成fingerpoint,然后对fingerpoint加密填入AH header中.
这种校验方式可以防止数据传输过程被第三方篡改,但IP数据区的数据还是明文,并没有真正加密.
    ESP则是真正意义上的加密.对数据加密后,数据区就会变成密文,无法直接识别,需要解密之后才能处理.
 

Posted by imouse 2012年10月11日 02:39