分类归档 操作系统

通过admin

Android SQLite 事务处理

应用程序初始化时需要批量的向sqlite中插入大量数据,单独的使用for+Insert方法导致应用响应缓慢,因为 sqlite插入数据的时候默认一条语句就是一个事务,有多少条数据就有多少次磁盘操作。我的应用初始5000条记录也就是要5000次读写磁盘操作。

而且不能保证所有数据都能同时插入。(有可能部分插入成功,另外一部分失败,后续还得删除。太麻烦)

解决方法:

添加事务处理,把5000条插入作为一个事务

 

我们使用SQLite的事务进行控制:

db.beginTransaction();  //手动设置开始事务

try{

//批量处理操作

for(Collection c:colls){

insert(db, c);

}

db.setTransactionSuccessful(); //设置事务处理成功,不设置会自动回滚不提交。

//在setTransactionSuccessful和endTransaction之间不进行任何数据库操作

}catch(Exception e){

MyLog.printStackTraceString(e);

}finally{

db.endTransaction(); //处理完成

}

1.使用SQLiteDatabase的beginTransaction()方法可以开启一个事务,程序执行到endTransaction() 方法时会检查事务的标志是否为成功,如果程序执行到endTransaction()之前调用了setTransactionSuccessful() 方法设置事务的标志为成功,则所有从beginTransaction()开始的操作都会被提交,如果没有调用setTransactionSuccessful() 方法则回滚事务。

2.使用例子如下:下面两条SQL语句在同一个事务中执行。

Java代码

  1. //银行账户事务测试
  1. public void payment()
  1. {
  1.     SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
  2.     //开启事务
  1.     db.beginTransaction();
  1.     try
  1.     {
  1.         db.execSQL(“update person set amount=amount-10 where personid=?”, new Object[]{1});
  1.         db.execSQL(“update person set amount=amount+10 where personid=?”, new Object[]{2});
  1.         //设置事务标志为成功,当结束事务时就会提交事务
  1.         db.setTransactionSuccessful();
  2.     }
  1.    catch(Exception e){
  2.         throw(e);
  1.     }
  1.     finally
  2.     {
  1.         //结束事务
  1.         db.endTransaction();
  1.     }
  2. }
通过admin

八款开源ANDROID游戏引擎

很多初学Android游戏开发的朋友,往往会显得有些无所适从,他们常常不知道该从何处入手,每当遇到自己无法解决的难题时,又往往会一边羡慕于 iPhone下有诸如Cocos2d-iphone之类的免费游戏引擎可供使用,一边自暴自弃的抱怨Android平台游戏开发难度太高,又连个像样的游戏引擎也没有,甚至误以为使用Java语言开发游戏是一件费力不讨好且没有出路的事情。

事实上,这种想法完全是没有必要且不符合实际的,作为能和苹果iOS分庭抗礼的Android(各种意义上),当然也会有相当数量的游戏引擎存在。仅仅因为我们处于这个狭小的天地间,与外界接触不够,所以对它们的存在茫然不知罢了。

 

下面我就罗列出八款常见的Android游戏引擎,以供有需要者参考(收费,下载量过小,不公布源码,以及鄙人不知道(-_-)的引擎不在此列)。

 

1、Angle

 

Angle是一款专为Android平台设计的,敏捷且适合快速开发的2D游戏引擎,基于OpenGL ES技术开发。该引擎全部用Java代码编写,并且可以根据自己的需要替换里面的实现,缺陷在于文档不足,而且下载的代码中仅仅包含有少量的示例教程。

 

最低运行环境要求不详。

 

项目地址:http://code.google.com/p/angle/

 

2、Rokon

 

rokon是一款Android 2D游戏引擎,基于OpenGL ES技术开发,物理引擎为Box2D,因此能够实现一些较为复杂的物理效果,该项目最新版本为 2.0.3 (09/07/10)。总体来说,此引擎最大的优点在于其开发文档相当之完备,并且项目作者对反馈Bug的修正非常之神速,所以该框架的使用在目前也最为广泛,有人干脆将它称为Cocos2d-iPhone引擎的Android版(业务逻辑和编码风格上也确实很像)。附带一提,国内某个需要注册会员才能下载的Android游戏框架衍生于此框架,所以大家也不要刻板的认为收费便一定是好的,免费就一定不好。

 

最低运行环境要求为Android 1.5。

 

项目地址:http://code.google.com/p/rokon/

 

3、LGame

 

LGame是一款国人开发的Java游戏引擎,有Android及PC(J2SE)两个开发版本,目前最高版本同为0.2.6(31/07/10)。其底层绘图器LGrpaphics封装有J2SE以及J2ME提供的全部Graphics API(PC版采用Graphics2D封装,Android版采用Canvas模拟实现),所以能够将J2SE或J2ME开发经验直接套用其中,两版本间主要代码能够相互移植。Android版内置有Admob接口,可以不必配置XML直接硬编码Admob广告信息。

 

该引擎除了基本的音效、图形、物理、精灵等常用组件以外,也内置有Ioc、xml、http等常用Java组件的封装,代价是jar体积较为庞大,PC版已突破1.2MB,Android版有所简化也在500KB左右。此外,该引擎还内置有按照1:1实现的J2ME精灵类及相关组件,可以将绝大多数 J2ME游戏平移到Android或PC版中。唯一遗憾的是,该项目作者是个极其懒惰的家伙,开发文档从去年说到今年依旧没有提供,只有游戏示例可供下载。

 

最低运行环境要求为Android 1.1。

 

项目地址:http://code.google.com/p/loon-simple/

 

4、AndEngine

 

andengine同样是一款基于OpenGL ES技术的Android游戏引擎,物理引擎同样为Box2D(标配|||)。该框架性能普通,文档缺乏,但示例较为丰富。

 

下载地址(未直接提供jar下载,源码可通过svn提取):http://code.google.com/p/andengine/

 

最低运行环境要求不详。

 

项目地址:http://code.google.com/p/rokon/

 

5、libgdx

 

libgdx是一款基于OpenGL ES技术开发的Android游戏引擎,支持Android平台下的2D游戏开发,物理引擎采用Box2D实现。单就性能角度来说,堪称是一款非常强大的 Android游戏引擎,但缺陷在于精灵类等相关组件在使用上不够简化,而且文档也较为匮乏。

 

最低运行环境要求不详。

 

项目地址:http://code.google.com/p/libgdx/

 

6、jPCT

 

jPCT是一款基于OpenGL技术开发的3D图形引擎(PC环境为标准OpenGL,Android为OpenGL ES),以Java语言为基础的,拥有功能强大的Java 3D解决方案。该引擎与LGame(此为2D游戏引擎)相类似,目前拥有PC(J2SE)以及Android两个开发版本。

 

jPCT的最大优势之一,就在于它惊人的向下兼容性。在PC环境中,jPCT甚至可以运行在JVM1.1环境之中,因为jPCT内部提供的图形渲染接口完全符合所有的Java 1.1规范(就连已经消失的Microsoft VM乃至更古老的Netscape 4 VM也不例外)。

 

最低运行环境要求为Android 1.5。

 

项目地址:http://www.jpct.net/jpct-ae/

 

7、Alien3d

 

Alien3d是一款体积非常之小的Android 3D游戏引擎,基于OpenGL ES技术开发。为了压缩体积,它根据不同功能采用多jar方式发布(包括alien3d-engine.jar,alien3d- tiled.jar,alien3d-sprites.jar,alien3d-shapes.jar,alien3d- particles2d.jar,),事实上它的核心文件大约只有40KB,所有相关jar的总和也不足150KB。

 

最低运行环境要求为Android 1.5。

 

项目地址:http://code.google.com/p/alien3d/

 

8、Catcake

 

Catcake是一款跨平台的Java 3D图形引擎,目前支持PC(J2SE)及Android环境运行(已有iPhone版规划)。该引擎在易用性和运行性能上皆有出色的表现,支持常见的游戏开发功能,诸如精灵动画,音频处理和视频播放等。

 

最低运行环境要求为Android 1.6。

 

项目地址:http://code.google.com/p/catcake/

 

源文档 <http://www.cnblogs.com/henryhu/archive/2011/02/10/1950983.html>

通过admin

linux cat 命令详解

使用方式:cat [-AbeEnstTuv] [–help] [–version] fileName

说明:把档案串连接后传到基本输出(萤幕或加 > fileName 到另一个档案)

参数:

-n 或 –number 由 1 开始对所有输出的行数编号

-b 或 –number-nonblank 和 -n 相似,只不过对于空白行不编号

-s 或 –squeeze-blank 当遇到有连续两行以上的空白行,就代换为一行的空白行

-v 或 –show-nonprinting

范例:

cat -n textfile1 > textfile2 把 textfile1 的档案内容加上行号后输入 textfile2 这个档案里

cat -b textfile1 textfile2 >> textfile3 把 textfile1 和 textfile2 的档案内容加上行号(空白行不加)之后将内容附加到 textfile3 里。

范例:

把 textfile1 的档案内容加上行号后输入 textfile2 这个档案里

cat -n textfile1 > textfile2

把 textfile1 和 textfile2 的档案内容加上行号(空白行不加)之后将内容附加到 textfile3 里。

cat -b textfile1 textfile2 >> textfile3

cat /dev/null > /etc/test.txt 此为清空/etc/test.txt档案内容

cat 也可以用来制作 image file。例如要制作软碟的 image file,将软碟放好后打

cat /dev/fd0 > OUTFILE

相反的,如果想把 image file 写到软碟,请打

cat IMG_FILE > /dev/fd0

注:

1. OUTFILE 指输出的 image 档名。

2. IMG_FILE 指 image file。

3. 若从 image file 写回 device 时,device 容量需与相当。

4. 通常用在制作开机磁片。

 

cat主要有三大功能:

1.一次显示整个文件。$ cat   filename

2.从键盘创建一个文件。$ cat  >  filename

只能创建新文件,不能编辑已有文件.

3.将几个文件合并为一个文件。 $cat   file1   file2  > file

参数:

-n 或 –number 由 1 开始对所有输出的行数编号

-b 或 –number-nonblank 和 -n 相似,只不过对于空白行不编号

-s 或 –squeeze-blank 当遇到有连续两行以上的空白行,就代换为一行的空白行

-v 或 –show-nonprinting

范例:

cat -n textfile1 > textfile2 把 textfile1 的档案内容加上行号后输入 textfile2 这个档案里

cat -b textfile1 textfile2 >> textfile3 把 textfile1 和 textfile2 的档案内容加上行号(空白行不加)之后将内容附加到 textfile3 里。

范例:

把 textfile1 的档案内容加上行号后输入 textfile2 这个档案里

cat -n textfile1 > textfile

把 textfile1 和 textfile2 的档案内容加上行号(空白行不加)之后将内容附加到 textfile3 里

cat -b textfile1 textfile2 >> textfile3

cat /dev/null > /etc/test.txt 此为清空/etc/test.txt档案内容

cat 也可以用来制作 image file。例如要制作软碟的 image file,将软碟放好后打

cat /dev/fd0 > OUTFILE %W

相反的,如果想把 image file 写到软碟,请打

cat IMG_FILE > /dev/fd0

注: &copy;Newboys — Newboys综合论坛

1. OUTFILE 指输出的 image 档名。

2. IMG_FILE 指 image file。

3. 若从 image file 写回 device 时,device 容量需与相当。

4. 通常用在制作开机磁片。

13.9. 使用 cat 来操作文件

Red Hat Linux 有一个工具程序,它能够帮助你保留简短列表,将这些列表收集起来,甚至向你透漏一点你的系统信息。

这个工具叫做 cat,它是 concatenate(连锁)的简写,意思是合并文件。

cat 命令还会在屏幕上显示整个文件的内容(譬如,键入 cat filename.txt)。如果文件较长,它会在屏幕上飞快地滚过。要防止这一效果的发生,使用 cat filename.txt | less 命令。

一起使用管道(|)和 less 命令会一页一页地显示文件。然后,你便可以使用向上或向下的箭头键在页码中向前或向后移动。关于使用管道来合并两个不同功能的详细信息,请参阅

第 13.10 节 

13.9.1. 使用重导向

重导向就是使 shell 改变它所认定的标准输出,或者改变标准输出的目标。

要重导向标准输出,使用 > 符号。把 > 符号放在 cat 命令之后(或在任何写入标准输出的工具程序和应用程序之后),会把它的输出重导向到跟在符号之后的文件中。

譬如,使用 cat 自身会在屏幕上输出你所输入的内容,如同是在重复你刚键入的行。下面的例子显示了 cat 会重复你输入的每一行:

 

图 13-5. cat 命令

要把 cat 的输出重导向到一个文件中,在 shell 提示下键入以下命令(按 [Enter] 键会把你带到一个空行):

cat > sneakers.txt

 

图 13-6. 把输出重导向到一个文件

按 [Enter] 键转到一个空行,然后使用 [Ctrl]-[D] 键来退出 cat。

注意到

图 13-6 

中的区别了吗?此处并没有重复显示。这是因为 cat 的标准输出已经被重导向了。重导向的地方是你刚刚制作的一个叫做 sneakers.txt 的崭新文件。

当你运行 cat 命令时,你会发现你所在目录中的文件

如前所示,你可以使用 cat 来读取文件。在提示下,键入:

cat sneakers.txt

 

小心

 

在你把输出重导向入文件时,请谨慎从事,因为你会很容易地覆盖一个现存文件!除非你想代替该文件,请确保你所创建的文件名与已经存在的文件名不一样。

再把输出重导向到另一个文件,暂且把它叫做 home.txt。在这个例子中,键入命令 cat > home.txt,然后按 [Enter],其后跟随:

bring the coffee home

take off shoes

put on sneakers

make some coffee

relax!

现在,在一个空行上,使用 [Ctrl]-[D] 键组合来退出 cat。

下一步,使用 cat 把 home.txt 和 sneakers.txt 连接起来,然后再把两个文件的输出重导向到一个叫做 saturday.txt 的新文件(你会在

图 13-7 

中发现一个示例)。键入下面的命令:

cat sneakers.txt home.txt > saturday.txt

 

图 13-7. 连接文件和重导向输出

你可以看到 cat 已经把 home.txt 添加到 sneakers.txt 的结尾处。

13.9.2. 后补标准输出

你可以使用输出重导向来在一个现存文件之后添加新信息。这与你使用 > 符号相似,你是在告诉 shell 把信息发送到标准输出之外的某个地方。

然而,当你使用 >> 时,你是在给文件添加信息,而不是完全替换文件内容。

最好的解释方法是向你演示实例。我们便使用刚才已创建的两个文件(sneakers.txt 和 home.txt),然后使用后补输出的符号把它们连接起来。你想把 home.txt 的信息添加到 sneakers.txt 的信息中去,因此键入:

cat home.txt >> sneakers.txt

现在,使用 cat sneakers.txt 的命令来检查一下。最终的输出在文件结尾处显示了 home.txt 的内容:

buy some sneakers

then go to the coffee shop

then buy some coffee

bring the coffee home

take off shoes

put on sneakers

make some coffee

relax!

你键入的命令把文件 home.txt 的输出后补到文件 sneakers.txt 中去。

通过后补输出,你利用了现存文件而不必创建新文件,从而为自己节省些时间(以及一些磁盘群集)。

现在比较一下文件 sneakers.txt 和文件 saturday.txt 的结果,你就会看到它们一模一样。要做比较,键入:

cat sneakers.txt; cat saturday.txt

这两个文件的内容都会被显示 — 先是 sneakers.txt 文件,然后是 saturday.txt 文件(如

图 13-8 

所示)。

 

图 13-8. 串联命令和比较文件

13.9.3. 重导向标准输入

你不但可以重导向标准输出,还可以重导向标准输入。

当你使用重导向标准输入符号

cat

因为你用来分隔 cat 命令和文件的是小于号(sneakers.txt 的输出就被 cat 命令读取。

 

图 13-9. 重导向标准输入

 

源文档 <http://blog.csdn.net/mecho/article/details/4325691>

 

通过admin

linux grep命令参数及用法详解—linux管道命令grep

功能说明:查找文件里符合条件的字符串。

语  法:grep [-abcEFGhHilLnqrsvVwxy][-A<显示列数>][-B<显示列数>][-C<显示列数>][-d<进行动作>][-e<范本样式>][-f<范本文件>][–help][范本样式][文件或目录…]

补充说明:grep 指令用于查找内容包含指定的范本样式的文件,如果发现某文件的内容符合所指定的范本样式,预设grep指令会把含有范本样式的那一列显示出来。若不指定任何文件名称,或是所给予的文件名为“-”,则grep指令会从标准输入设备读取数据。

参  数:
-a或–text   不要忽略二进制的数据。
-A<显示列数>或–after-context=<显示列数>   除了显示符合范本样式的那一列之外,并显示该列之后的内容。
-b或–byte-offset   在显示符合范本样式的那一列之前,标示出该列第一个字符的位编号。
-B<显示列数>或–before-context=<显示列数>   除了显示符合范本样式的那一列之外,并显示该列之前的内容。
-c或–count   计算符合范本样式的列数。
-C<显示列数>或–context=<显示列数>或-<显示列数>   除了显示符合范本样式的那一列之外,并显示该列之前后的内容。
-d<进行动作>或–directories=<进行动作>   当指定要查找的是目录而非文件时,必须使用这项参数,否则grep指令将回报信息并停止动作。
-e<范本样式>或–regexp=<范本样式>   指定字符串做为查找文件内容的范本样式。
-E或–extended-regexp   将范本样式为延伸的普通表示法来使用。
-f<范本文件>或–file=<范本文件>   指定范本文件,其内容含有一个或多个范本样式,让grep查找符合范本条件的文件内容,格式为每列一个范本样式。
-F或–fixed-regexp   将范本样式视为固定字符串的列表。
-G或–basic-regexp   将范本样式视为普通的表示法来使用。
-h或–no-filename   在显示符合范本样式的那一列之前,不标示该列所属的文件名称。
-H或–with-filename   在显示符合范本样式的那一列之前,表示该列所属的文件名称。
-i或–ignore-case   忽略字符大小写的差别。
-l或–file-with-matches   列出文件内容符合指定的范本样式的文件名称。
-L或–files-without-match   列出文件内容不符合指定的范本样式的文件名称。
-n或–line-number   在显示符合范本样式的那一列之前,标示出该列的列数编号。
-q或–quiet或–silent   不显示任何信息。
-r或–recursive   此参数的效果和指定“-d recurse”参数相同。
-s或–no-messages   不显示错误信息。
-v或–revert-match   反转查找。
-V或–version   显示版本信息。
-w或–word-regexp   只显示全字符合的列。
-x或–line-regexp   只显示全列符合的列。
-y   此参数的效果和指定“-i”参数相同。
–help   在线帮助。

linux grep命令的使用
用grep命令 搜索文本文件 来自www.linuxso.com

如果您要在几个文本文件中查找一字符串,可以使用&lsquo;grep’命令。‘grep’在文本中搜索指定的字符串。
假设您正在‘/usr/src/linux/Documentation’目录下搜索带字符串‘magic’的文件:
$ grep magic /usr/src/linux/Documentation/*
sysrq.txt:* How do I enable the magic SysRQ key?
sysrq.txt:* How do I use the magic SysRQ key?
其中文件‘sysrp.txt’包含该字符串,讨论的是 SysRQ 的功能。
默认情况下,‘grep’只搜索当前目录。如果此目录下有许多子目录,‘grep’会以如下形式列出:
grep: sound: Is a directory
这可能会使‘grep’的输出难于阅读。这里有两种解决的办法:
明确要求搜索子目录:grep -r
或忽略子目录:grep -d skip
当然,如果预料到有许多输出,您可以通过 管道 将其转到‘less’上阅读
$ grep magic /usr/src/linux/Documentation/* | less
这样,您就可以更方便地阅读。
有一点要注意,您必需提供一个文件过滤方式(搜索全部文件的话用 *)。如果您忘了,‘grep’会一直等着,直到该程序被中断。如果您遇到了这样的情况,按 <CTRL c> ,然后再试。
下面是一些有意思的命令行参数:
grep -i pattern files :不区分大小写地搜索。默认情况区分大小写,
grep -l pattern files :只列出匹配的文件名,
grep -L pattern files :列出不匹配的文件名,
grep -w pattern files :只匹配整个单词,而不是字符串的一部分(如匹配‘magic’,而不是‘magical’),
grep -C number pattern files :匹配的上下文分别显示[number]行,
grep pattern1 | pattern2 files :显示匹配 pattern1 或 pattern2 的行,
grep pattern1 files | grep pattern2 :显示既匹配 pattern1 又匹配 pattern2 的行。
这里还有些用于搜索的特殊符号:
< 和 > 分别标注单词的开始与结尾。
例如:
grep man * 会匹配 ‘Batman’、‘manic’、‘man’等,
grep \'<man\’ * 匹配‘manic’和‘man’,但不是‘Batman’,
grep \'<man>\’ 只匹配‘man’,而不是‘Batman’或‘manic’等其他的字符串。
\’^\’:指匹配的字符串在行首,
\’$\’:指匹配的字符串在行尾,
如果您不习惯命令行参数,可以试试图形界面的‘grep’,如 reXgrep 。这个软件提供 AND、OR、NOT 等语法,还有漂亮的按钮 🙂 。如果您只是需要更清楚的输出,不妨试试 fungrep 。

.grep 搜索字符串
命令格式:
grep string filename
寻找字串的方法很多,比如说我想找所有以M开头的行.此时必须引进pattern的观
念.以下是一些简单的□例,以及说明:
^M 以M开头的行,^表示开始的意思
M$ 以M结尾的行,$表示结束的意思
^[0-9] 以数字开始的行,[]内可列举字母
^[124ab] 以1,2,4,a,或b开头的行
^b.503 句点表示任一字母
* 星号表示0个以上的字母(可以没有)
+ 加号表示1个以上的字母
. 斜线可以去掉特殊意义
<eg> cat passwd | grep ^b 列出大学部有申请帐号者名单
cat passwd | grep ^s 列出交换学生申请帐号者名单
cat passwd | grep \’^b.503\’ 列出电机系各年级…
grep \’^.\’ myfile.txt 列出所有以句点开头的行

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

1. grep简介

 

grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。Unix的grep家族包 括grep、egrepfgrep。egrep和fgrep的命令只跟grep有很小不同。egrep是grep的扩展,支持更多的re元字符, fgrep就是fixed grep或fast grep,它们把所有的字母都看作单词,也就是说,正则表达式中的元字符表示回其自身的字面意义,不再特殊。linux使用GNU版本的grep。它功能 更强,可以通过-G、-E、-F命令行选项来使用egrep和fgrep的功能。

grep的工作方式是这样的,它在一个或多个文件中搜索字符串模板。如果模板包括空格,则必须被引用,模板后的所有字符串被看作文件名。搜索的结果被送到屏幕,不影响原文件内容。

grep可用于shell脚本,因为grep通过返回一个状态值来说明搜索的状态,如果模板搜索成功,则返回0,如果搜索不成功,则返回1,如果搜索的文件不存在,则返回2。我们利用这些返回值就可进行一些自动化的文本处理工作。
2. grep正则表达式元字符集(基本集)

 

^

锚定行的开始 如:\’^grep\’匹配所有以grep开头的行。

$

锚定行的结束 如:\’grep$\’匹配所有以grep结尾的行。

匹配一个非换行符的字符 如:\’gr.p\’匹配gr后接一个任意字符,然后是p。

*

匹配零个或多个先前字符 如:\’*grep\’匹配所有一个或多个空格后紧跟grep的行。 .*一起用代表任意字符。

[]

匹配一个指定范围内的字符,如\'[Gg]rep\’匹配Grep和grep。

[^]

匹配一个不在指定范围内的字符,如:\'[^A-FH-Z]rep\’匹配不包含A-R和T-Z的一个字母开头,紧跟rep的行。

(..)

标记匹配字符,如\'(love)\’,love被标记为1。

<

锚定单词的开始,如:\’

>

锚定单词的结束,如\’grep>\’匹配包含以grep结尾的单词的行。

x{m}

重复字符x,m次,如:\’0{5}\’匹配包含5个o的行。

x{m,}

重复字符x,至少m次,如:\’o{5,}\’匹配至少有5个o的行。

x{m,n}

重复字符x,至少m次,不多于n次,如:\’o{5,10}\’匹配5–10个o的行。

w

匹配文字和数字字符,也就是[A-Za-z0-9],如:\’Gw*p\’匹配以G后跟零个或多个文字或数字字符,然后是p。

W

w的反置形式,匹配一个或多个非单词字符,如点号句号等。

 

b

单词锁定符,如: \’bgrepb\’只匹配grep。

3. 用于egrep和 grep -E的元字符扩展集

+

匹配一个或多个先前的字符。如:\'[a-z]+able\’,匹配一个或多个小写字母后跟able的串,如loveable,enable,disable等。

?

匹配零个或多个先前的字符。如:\’gr?p\’匹配gr后跟一个或没有字符,然后是p的行。

a|b|c

匹配a或b或c。如:grep|sed匹配grep或sed

()

分组符号,如:love(able|rs)ov+匹配loveable或lovers,匹配一个或多个ov。

x{m},x{m,},x{m,n}

作用同x{m},x{m,},x{m,n}

4. POSIX字符类

为了在不同国家的字符编码中保持一至,POSIX(The Portable Operating System Interface)增加了特殊的字符类,如[:alnum:]是A-Za-z0-9的另一个写法。要把它们放到[]号内才能成为正则表达式,如[A- Za-z0-9]或[[:alnum:]]。在linux下的grep除fgrep外,都支持POSIX的字符类。

[:alnum:]

文字数字字符

[:alpha:]

文字字符

[:digit:]

数字字符

[:graph:]

非空字符(非空格、控制字符)

[:lower:]

小写字符

[:cntrl:]

控制字符

[:print:]

非空字符(包括空格)

[:punct:]

标点符号

[:space:]

所有空白字符(新行,空格,制表符)

[:upper:]

大写字符

[:xdigit:]

十六进制数字(0-9,a-f,A-F)

5. Grep命令选项

-?

同时显示匹配行上下的?行,如:grep -2 pattern filename同时显示匹配行的上下2行。

-b,–byte-offset

打印匹配行前面打印该行所在的块号码。

-c,–count

只打印匹配的行数,不显示匹配的内容。

-f File,–file=File

从文件中提取模板。空文件中包含0个模板,所以什么都不匹配。

-h,–no-filename

当搜索多个文件时,不显示匹配文件名前缀。

-i,–ignore-case

忽略大小写差别。

-q,–quiet

取消显示,只返回退出状态。0则表示找到了匹配的行。

-l,–files-with-matches

打印匹配模板的文件清单。

-L,–files-without-match

打印不匹配模板的文件清单。

-n,–line-number

在匹配的行前面打印行号。

-s,–silent

不显示关于不存在或者无法读取文件的错误信息。

-v,–revert-match

反检索,只显示不匹配的行。

-w,–word-regexp

如果被<和>引用,就把表达式做为一个单词搜索。

-V,–version

显示软件版本信息。

6. 实例

要用好grep这个工具,其实就是要写好正则表达式,所以这里不对grep的所有功能进行实例讲解,只列几个例子,讲解一个正则表达式的写法。

$ ls -l | grep \’^a\’

通过管道过滤ls -l输出的内容,只显示以a开头的行。

$ grep \’test\’ d*

显示所有以d开头的文件中包含test的行。

$ grep \’test\’ aa bb cc

显示在aa,bb,cc文件中匹配test的行。

$ grep \'[a-z]{5}\’ aa

显示所有包含每个字符串至少有5个连续小写字符的字符串的行。

$ grep \’w(es)t.*1\’ aa

如果west被匹配,则es就被存储到内存中,并标记为1,然后搜索任意个字符(.*),这些字符后面紧跟着另外一个es(1),找到就显示该行。如果用egrep或grep -E,就不用””号进行转义,直接写成\’w(es)t.*1\’就可以了。

http://www.linuxso.com/command/grep.html

linux grep命令参数及用法详解—linux管道命令grep

通过admin

【原】自己动手实现动态外网ip管理和动态DNS域名解析

项目背景:

在自己的电脑装了linux 虚拟机,想要在外网也能ssh到虚拟机进行开发,由于路由ip是动态ip,想到网上找一些动态dns域名解析,但是效果不大好,所以想到自己进行外网ip的管理。

 

想法:

用C++写一个界面客户端,随系统启动,定时访问自己的cgi,更新自己的外网ip;这个客户端能支持简单的几个操作:启动,退出,设置更新间隔,是否随系统启动等。

写一个cgi,接收client请求,并记录最新的外网ip到数据库;

写另外一个cgi,在其他地方访问能列出当前最新的外网ip,以及历史ip列表。

可以再写一个跳转cgi:jump.php,访问这个cgi能够自动跳转到最新的外网ip对应的目录。

 

至此,一个简单的动态ip管理和dns解析功能就完成了。

 

编程环境选择:

Client:C++,MFC;

Server:Php+Mysql,服务器使用sina云平台。

 

项目进度:

编写CGI,updateip.php?m=update&uid=实现更新外网ip到数据库。

Php中获取ip的方式:

$ip=@$REMOTE_ADDR;

echo “<b>IP Address= $ip</b>”;

$ip=$_SERVER[‘REMOTE_ADDR’];

数据库设计:

Iplist:

建表:

Create table iplist(id int not null auto_increment,

Primary key(id),

uid VARCHAR(32),

ip VARCHAR(32),

updatetime datetime

)

 

<html>

<body>

 

CGi代码:

Update.php

<?php

$method = $_GET[‘m’];

if($method == “update”){

$ip=$_SERVER[‘REMOTE_ADDR’];

$uid = $_GET[‘uid’];

echo ‘Got it:uid=’.$uid.’,ip=’.$ip.'</BR>’;

 

//mysql_connect($_SAE_MYSQL_HOST_M,$_SAE_MYSQL_USER, $_SAE_MYSQL_PASS) or die(mysql_error());

//mysql_select_db($_SAE_MYSQL_DB) or die(mysql_error());

 

// Create a MySQL table in the selected database

 

$mysql = new SaeMysql();

 

$sql = “INSERT INTO `iplist` (`id`, `uid`, `ip`, `updatetime`) VALUES (NULL, ‘”.$uid.”‘, ‘”.$ip.”‘, now());”;

$mysql->runSql( $sql );

if( $mysql->errno() != 0 )

{

die( “Error:” . $mysql->errmsg() );

}

 

$mysql->closeDb();

 

 

}else{

$mysql = new SaeMysql();

$sql = “SELECT *

FROM `iplist`

ORDER BY `updatetime` DESC”;

 

$data = $mysql->getData( $sql );

foreach($data as $i => $value){

echo “Record:id=”.$value[‘id’].”,uid=”.$value[‘uid’].”,ip”.$value[‘ip’].”,updatetime”.$value[‘updatetime’].”</BR></BR>”;

}

 

if( $mysql->errno() != 0 )

{

die( “Error:” . $mysql->errmsg() );

}

 

$mysql->closeDb();

 

 

}

 

 

?>

 

</body>

</html>

 

用MFC编写一个简单的客户端,开机自动启动,定时请求服务器更新外网ip

 

client端主要代码,基于VS2005,MFC:

UpdateIp.rc
// Microsoft Visual C++ generated resource script.

//

#include “resource.h”

 

#define APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////

//

// Generated from the TEXTINCLUDE 2 resource.

//

#include “afxres.h”

 

/////////////////////////////////////////////////////////////////////////////

#undef APSTUDIO_READONLY_SYMBOLS

 

/////////////////////////////////////////////////////////////////////////////

// Chinese (P.R.C.) resources

 

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)

#ifdef _WIN32

LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED

#pragma code_page(936)

#endif //_WIN32

 

#ifdef APSTUDIO_INVOKED

/////////////////////////////////////////////////////////////////////////////

//

// TEXTINCLUDE

//

 

1 TEXTINCLUDE

BEGIN

“resource.h\0”

END

 

2 TEXTINCLUDE

BEGIN

“#include “”afxres.h””\r\n”

“\0”

END

 

3 TEXTINCLUDE

BEGIN

“#define _AFX_NO_SPLITTER_RESOURCES\r\n”

“#define _AFX_NO_OLE_RESOURCES\r\n”

“#define _AFX_NO_TRACKER_RESOURCES\r\n”

“#define _AFX_NO_PROPERTY_RESOURCES\r\n”

“\r\n”

“#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)\r\n”

“LANGUAGE 4, 2\r\n”

“#pragma code_page(936)\r\n”

“#include “”res\\UpdateIp.rc2″”  // non-Microsoft Visual C++ edited resources\r\n”

“#include “”afxres.rc””     // Standard components\r\n”

“#endif\r\n”

“\0”

END

 

#endif    // APSTUDIO_INVOKED

 

 

/////////////////////////////////////////////////////////////////////////////

//

// Icon

//

 

// Icon with lowest ID value placed first to ensure application icon

// remains consistent on all systems.

IDR_MAINFRAME           ICON                    “res\\UpdateIp.ico”

 

/////////////////////////////////////////////////////////////////////////////

//

// Dialog

//

 

IDD_ABOUTBOX DIALOGEX 0, 0, 235, 55

STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU

CAPTION “About UpdateIp”

FONT 8, “MS Shell Dlg”, 0, 0, 0x1

BEGIN

ICON            IDR_MAINFRAME,IDC_STATIC,11,17,20,20

LTEXT           “UpdateIp Version 1.0”,IDC_STATIC,40,10,119,8,SS_NOPREFIX

LTEXT           “Copyright (C) 2012”,IDC_STATIC,40,25,119,8

DEFPUSHBUTTON   “OK”,IDOK,178,7,50,16,WS_GROUP

END

 

IDD_UPDATEIP_DIALOG DIALOGEX 0, 0, 144, 222

STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU

EXSTYLE WS_EX_APPWINDOW

CAPTION “UpdateIp”

FONT 8, “MS Shell Dlg”, 0, 0, 0x1

BEGIN

PUSHBUTTON      “停止服务”,IDC_BTN_STOPSERVICE,81,89,50,14

PUSHBUTTON      “启动服务”,IDC_BTN_STARTSERVICE,17,89,50,14

CONTROL         “随系统启动”,IDC_CHECK_AUTOSTART,”Button”,BS_AUTOCHECKBOX | WS_TABSTOP,19,25,56,10

EDITTEXT        IDC_EDIT_UPDATEINTERVAL,82,46,40,14,ES_AUTOHSCROLL | ES_NUMBER

LTEXT           “更新间隔(秒):”,IDC_STATIC,18,49,60,8

GROUPBOX        “设置”,IDC_STATIC,0,5,135,212

PUSHBUTTON      “保存”,IDC_SAVE,17,63,50,14

EDITTEXT        IDC_EDIT_RESULT,12,119,119,88,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | WS_VSCROLL,WS_EX_STATICEDGE

END

 

 

/////////////////////////////////////////////////////////////////////////////

//

// Version

//

 

VS_VERSION_INFO VERSIONINFO

FILEVERSION 1,0,0,1

PRODUCTVERSION 1,0,0,1

FILEFLAGSMASK 0x3fL

#ifdef _DEBUG

FILEFLAGS 0x1L

#else

FILEFLAGS 0x0L

#endif

FILEOS 0x4L

FILETYPE 0x1L

FILESUBTYPE 0x0L

BEGIN

BLOCK “StringFileInfo”

BEGIN

BLOCK “040904e4”

BEGIN

VALUE “CompanyName”, “TODO: <Company name>”

VALUE “FileDescription”, “TODO: <File description>”

VALUE “FileVersion”, “1.0.0.1”

VALUE “InternalName”, “UpdateIp.exe”

VALUE “LegalCopyright”, “TODO: (c) <Company name>.  All rights reserved.”

VALUE “OriginalFilename”, “UpdateIp.exe”

VALUE “ProductName”, “TODO: <Product name>”

VALUE “ProductVersion”, “1.0.0.1”

END

END

BLOCK “VarFileInfo”

BEGIN

VALUE “Translation”, 0x409, 1252

END

END

 

 

/////////////////////////////////////////////////////////////////////////////

//

// DESIGNINFO

//

 

#ifdef APSTUDIO_INVOKED

GUIDELINES DESIGNINFO

BEGIN

IDD_ABOUTBOX, DIALOG

BEGIN

LEFTMARGIN, 7

RIGHTMARGIN, 228

TOPMARGIN, 7

BOTTOMMARGIN, 48

END

 

IDD_UPDATEIP_DIALOG, DIALOG

BEGIN

RIGHTMARGIN, 142

END

END

#endif    // APSTUDIO_INVOKED

 

 

/////////////////////////////////////////////////////////////////////////////

//

// String Table

//

 

STRINGTABLE

BEGIN

IDS_ABOUTBOX            “&About UpdateIp…”

IDP_SOCKETS_INIT_FAILED “Windows sockets initialization failed.”

END

 

#endif    // Chinese (P.R.C.) resources

/////////////////////////////////////////////////////////////////////////////

 

 

 

#ifndef APSTUDIO_INVOKED

/////////////////////////////////////////////////////////////////////////////

//

// Generated from the TEXTINCLUDE 3 resource.

//

#define _AFX_NO_SPLITTER_RESOURCES

#define _AFX_NO_OLE_RESOURCES

#define _AFX_NO_TRACKER_RESOURCES

#define _AFX_NO_PROPERTY_RESOURCES

 

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)

LANGUAGE 4, 2

#pragma code_page(936)

#include “res\UpdateIp.rc2”  // non-Microsoft Visual C++ edited resources

#include “afxres.rc”     // Standard components

#endif

 

/////////////////////////////////////////////////////////////////////////////

#endif    // not APSTUDIO_INVOKED

 

 

UpdateIpDlg.h

// UpdateIpDlg.h : header file

//

 

#pragma once

 

 

// CUpdateIpDlg dialog

class CUpdateIpDlg : public CDialog

{

// Construction

public:

CUpdateIpDlg(CWnd* pParent = NULL);        // standard constructor

 

// Dialog Data

enum { IDD = IDD_UPDATEIP_DIALOG };

 

protected:

virtual void DoDataExchange(CDataExchange* pDX);        // DDX/DDV support

 

 

// Implementation

protected:

HICON m_hIcon;

 

// Generated message map functions

virtual BOOL OnInitDialog();

afx_msg void OnSysCommand(UINT nID, LPARAM lParam);

afx_msg void OnPaint();

afx_msg HCURSOR OnQueryDragIcon();

DECLARE_MESSAGE_MAP()

public:

afx_msg void OnBnClickedBtnStartservice();

afx_msg void OnBnClickedBtnStopservice();

afx_msg void OnTimer(UINT_PTR nIDEvent );

afx_msg void OnDestroy();

BOOL OnEraseBkgnd(CDC* pDC);

int OnCreate(LPCREATESTRUCT lpCreateStruct);

LRESULT OnNotifyIcon(WPARAM wParam,LPARAM IParam);

 

private:

void startService(int interval);

void stopService();

 

void startUpdateInstance();

void stopUpdateInstance();

 

BOOL setAutoStart(BOOL bVal);

void initSettings();

BOOL saveSettings();

CString getSettingFilePath();

void addNotification();

 

 

 

public:

afx_msg void OnBnClickedSave();

 

private:

int m_nTimer;

BOOL m_bAutoStart;

int m_nUpdateInterval;

int m_bIsRunning;

CString m_strSettingFilepath;

NOTIFYICONDATA NotifyIcon;

};

 

 

UpdateIpDlg.cpp

// UpdateIpDlg.cpp : implementation file

//

 

#include “stdafx.h”

#include “UpdateIp.h”

#include “UpdateIpDlg.h”

#include “lib/happyhttp.h”

 

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

 

#define WM_NC (WM_USER+1001)

const int TIMER_UPDATE = 100;

const TCHAR c_szSettingFilename[] = _T(“updateip.ini”);

const int c_nDefaultUpdate = 300;

const char c_szRequestHost[] = “xx.sinaapp.com”;     //换成自己的域名

 

// CAboutDlg dialog used for App About

 

class CAboutDlg : public CDialog

{

public:

CAboutDlg();

 

// Dialog Data

enum { IDD = IDD_ABOUTBOX };

 

protected:

virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

 

// Implementation

protected:

DECLARE_MESSAGE_MAP()

};

 

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

{

}

 

void CAboutDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

}

 

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

END_MESSAGE_MAP()

 

 

// CUpdateIpDlg dialog

 

 

 

 

CUpdateIpDlg::CUpdateIpDlg(CWnd* pParent /*=NULL*/)

: CDialog(CUpdateIpDlg::IDD, pParent)

, m_nTimer(0)

, m_bAutoStart(TRUE)

, m_nUpdateInterval(c_nDefaultUpdate)

, m_bIsRunning(FALSE)

, m_strSettingFilepath(_T(“”))

{

m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

 

void CUpdateIpDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

}

 

BEGIN_MESSAGE_MAP(CUpdateIpDlg, CDialog)

ON_WM_SYSCOMMAND()

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

ON_WM_TIMER()

ON_WM_DESTROY()

ON_WM_CREATE()

ON_WM_ERASEBKGND()

//}}AFX_MSG_MAP

ON_BN_CLICKED(IDC_BTN_STARTSERVICE, &CUpdateIpDlg::OnBnClickedBtnStartservice)

ON_BN_CLICKED(IDC_BTN_STOPSERVICE, &CUpdateIpDlg::OnBnClickedBtnStopservice)

ON_BN_CLICKED(IDC_SAVE, &CUpdateIpDlg::OnBnClickedSave)

ON_MESSAGE(WM_NC,OnNotifyIcon)

END_MESSAGE_MAP()

 

 

// CUpdateIpDlg message handlers

 

BOOL CUpdateIpDlg::OnInitDialog()

{

CDialog::OnInitDialog();

 

// Add “About…” menu item to system menu.

 

// IDM_ABOUTBOX must be in the system command range.

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX < 0xF000);

 

CMenu* pSysMenu = GetSystemMenu(FALSE);

if (pSysMenu != NULL)

{

CString strAboutMenu;

strAboutMenu.LoadString(IDS_ABOUTBOX);

if (!strAboutMenu.IsEmpty())

{

pSysMenu->AppendMenu(MF_SEPARATOR);

pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

}

}

 

// Set the icon for this dialog.  The framework does this automatically

//  when the application’s main window is not a dialog

SetIcon(m_hIcon, TRUE);                        // Set big icon

SetIcon(m_hIcon, FALSE);                // Set small icon

 

// TODO: Add extra initialization here

initSettings();

 

GetDlgItem(IDC_BTN_STARTSERVICE)->EnableWindow(FALSE);

GetDlgItem(IDC_BTN_STOPSERVICE)->EnableWindow(TRUE);

 

m_bIsRunning = TRUE;

startService(m_nUpdateInterval);

startUpdateInstance();

 

return TRUE;  // return TRUE  unless you set the focus to a control

}

 

void CUpdateIpDlg::OnSysCommand(UINT nID, LPARAM lParam)

{

if ((nID & 0xFFF0) == IDM_ABOUTBOX)

{

CAboutDlg dlgAbout;

dlgAbout.DoModal();

}else if ((nID & 0xFFF0) == SC_MINIMIZE )

{

ShowWindow(SW_HIDE);

}

else

{

CDialog::OnSysCommand(nID, lParam);

}

}

 

// If you add a minimize button to your dialog, you will need the code below

//  to draw the icon.  For MFC applications using the document/view model,

//  this is automatically done for you by the framework.

 

void CUpdateIpDlg::OnPaint()

{

if (IsIconic())

{

CPaintDC dc(this); // device context for painting

 

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

 

// Center icon in client rectangle

int cxIcon = GetSystemMetrics(SM_CXICON);

int cyIcon = GetSystemMetrics(SM_CYICON);

CRect rect;

GetClientRect(&rect);

int x = (rect.Width() – cxIcon + 1) / 2;

int y = (rect.Height() – cyIcon + 1) / 2;

 

// Draw the icon

dc.DrawIcon(x, y, m_hIcon);

}

else

{

CDialog::OnPaint();

}

}

 

// The system calls this function to obtain the cursor to display while the user drags

//  the minimized window.

HCURSOR CUpdateIpDlg::OnQueryDragIcon()

{

return static_cast<HCURSOR>(m_hIcon);

}

 

 

 

 

void CUpdateIpDlg::OnBnClickedBtnStartservice()

{

// TODO: Add your control notification handler code here

GetDlgItem(IDC_BTN_STARTSERVICE)->EnableWindow(FALSE);

GetDlgItem(IDC_BTN_STOPSERVICE)->EnableWindow(TRUE);

startService(m_nUpdateInterval);

}

 

void CUpdateIpDlg::OnBnClickedBtnStopservice()

{

// TODO: Add your control notification handler code here

GetDlgItem(IDC_BTN_STARTSERVICE)->EnableWindow(TRUE);

GetDlgItem(IDC_BTN_STOPSERVICE)->EnableWindow(FALSE);

stopService();

}

 

void CUpdateIpDlg::OnTimer(UINT_PTR nIDEvent ){

startUpdateInstance();

}

 

void CUpdateIpDlg::OnDestroy(){

Shell_NotifyIcon(NIM_DELETE, &NotifyIcon);

 

return CDialog::OnDestroy();

}

 

BOOL CUpdateIpDlg::OnEraseBkgnd(CDC* pDC){

 

static bool bFirst=true;

if(bFirst)

{

bFirst=false;

ShowWindow(SW_HIDE);

return TRUE;

}

 

return CDialog::OnEraseBkgnd(pDC);

}

 

int CUpdateIpDlg::OnCreate(LPCREATESTRUCT lpCreateStruct){

addNotification();

 

return CDialog::OnCreate(lpCreateStruct);

}

 

void CUpdateIpDlg::startService(int interval){

m_nTimer = SetTimer(TIMER_UPDATE,interval * 1000,0);

m_bIsRunning = TRUE;

 

CString strResult;

GetDlgItemText(IDC_EDIT_RESULT,strResult);

strResult += _T(“startService:\r\n”);

SetDlgItemText(IDC_EDIT_RESULT,strResult);

}

 

void CUpdateIpDlg::stopService(){

KillTimer(m_nTimer);

stopUpdateInstance();

m_bIsRunning = FALSE;

 

CString strResult;

GetDlgItemText(IDC_EDIT_RESULT,strResult);

strResult += _T(“stopService:\r\n”);

SetDlgItemText(IDC_EDIT_RESULT,strResult);

}

 

int count=0;

 

void OnBegin( const happyhttp::Response* r, void* userdata )

{

printf( “BEGIN (%d %s)\n”, r->getstatus(), r->getreason() );

count = 0;

}

 

void OnData( const happyhttp::Response* r, void* userdata, const unsigned char* data, int n )

{

fwrite( data,1,n, stdout );

count += n;

}

 

void OnComplete( const happyhttp::Response* r, void* userdata )

{

printf( “COMPLETE (%d bytes)\n”, count );

}

 

void CUpdateIpDlg::startUpdateInstance(){

//启动新的线程去发起Http请求

stopUpdateInstance();

CString strResult;

GetDlgItemText(IDC_EDIT_RESULT,strResult);

strResult += _T(“启动更新请求:\r\n”);

SetDlgItemText(IDC_EDIT_RESULT,strResult);

 

try

{

char uid[] = “0000”;

char szTemp[1024] = {0};

_snprintf_s(szTemp,sizeof(szTemp),sizeof(szTemp),”/updateip.php?m=update&uid=%s”,uid);

 

 

happyhttp::Connection conn(c_szRequestHost, 80 );

conn.setcallbacks( OnBegin, OnData, OnComplete, 0 );

 

conn.request( “GET”, szTemp, 0, 0,0 );

 

while( conn.outstanding() )

conn.pump();

 

/*

TCHAR uid[] = _T(“0000”);

TCHAR szTemp[1024] = {0};

_sntprintf_s(szTemp,sizeof(szTemp),sizeof(szTemp),_T(“/updateip.php?m=update&uid=%s”),uid);

 

 

BOOL  bResults = FALSE;

HINTERNET hSession = NULL,

hConnect = NULL,

hRequest = NULL;

 

// Use WinHttpOpen to obtain a session handle.

hSession = WinHttpOpen(  L”A WinHTTP Example Program/1.0″,

WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,

WINHTTP_NO_PROXY_NAME,

WINHTTP_NO_PROXY_BYPASS, 0);

 

// Specify an HTTP server.

if (hSession)

hConnect = WinHttpConnect( hSession, c_szRequestHost,

INTERNET_DEFAULT_HTTP_PORT, 0);

 

// Create an HTTP Request handle.

if (hConnect)

hRequest = WinHttpOpenRequest( hConnect, L”PUT”, szTemp,

NULL, WINHTTP_NO_REFERER,

WINHTTP_DEFAULT_ACCEPT_TYPES, 0);

 

// Send a Request.

if (hRequest)

bResults = WinHttpSendRequest( hRequest,

WINHTTP_NO_ADDITIONAL_HEADERS, 0,

WINHTTP_NO_REQUEST_DATA, 0,

0, 0);

 

// Place additional code here.

 

 

// Report errors.

if (!bResults{

CString strResult;

GetDlgItemText(IDC_EDIT_RESULT,strResult);

strResult += _T(“请求发送失败,URL = “);

strResult += c_szRequestHost;

strResult += szTemp;

strResult += “\r\n”;

SetDlgItemText(IDC_EDIT_RESULT,strResult);

}else{

CString strResult;

GetDlgItemText(IDC_EDIT_RESULT,strResult);

strResult += _T(“请求发送成功,URL = “);

strResult += c_szRequestHost;

strResult += szTemp;

strResult += “\r\n”;

SetDlgItemText(IDC_EDIT_RESULT,strResult);

}

printf(“Error %d has occurred.\n”,GetLastError());

 

 

 

// Close open handles.

if (hRequest) WinHttpCloseHandle(hRequest);

if (hConnect) WinHttpCloseHandle(hConnect);

if (hSession) WinHttpCloseHandle(hSession);*/

}catch( happyhttp::Wobbly& e )

{

printf(“Exception:\n%s\n”, e.what() );

}

 

 

}

 

void CUpdateIpDlg::stopUpdateInstance(){

CString strResult;

GetDlgItemText(IDC_EDIT_RESULT,strResult);

strResult += _T(“停止更新请求:\r\n”);

SetDlgItemText(IDC_EDIT_RESULT,strResult);

 

}

 

BOOL CUpdateIpDlg::setAutoStart(BOOL bVal){

HKEY hKey;

long return_val = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L”Software\\Microsoft\\Windows\\CurrentVersion\\Run”,0,KEY_READ| KEY_WRITE,&hKey );

if (ERROR_SUCCESS == return_val)

{

if (bVal)

{

TCHAR pathtofile[MAX_PATH] = {0};

GetModuleFileName(NULL,pathtofile,MAX_PATH);

 

if (ERROR_SUCCESS != RegSetValueEx(hKey,_T(“autoupdateip”),0,REG_SZ,(byte *)pathtofile,sizeof(pathtofile)))

{

RegCloseKey(hKey);

return FALSE;

}

 

}else{

long ret = RegDeleteValue(hKey,_T(“autoupdateip”));

if (ERROR_SUCCESS != ret && ret != ERROR_FILE_NOT_FOUND)

{

int err = GetLastError();

 

RegCloseKey(hKey);

return FALSE;

}

}

 

RegCloseKey(hKey);

 

return TRUE;

 

}

 

return FALSE;

}

 

void CUpdateIpDlg::OnBnClickedSave()

{

// TODO: Add your control notification handler code here

m_bAutoStart = ((CButton *)GetDlgItem(IDC_CHECK_AUTOSTART))->GetCheck();

if (!setAutoStart(m_bAutoStart))

{

MessageBox(_T(“setAutoStart error!”));

}

 

 

m_nUpdateInterval = GetDlgItemInt(IDC_EDIT_UPDATEINTERVAL);

if (m_bIsRunning)

{

stopService();

startService(m_nUpdateInterval);

}

 

if(!saveSettings()){

MessageBox(_T(“saveSettings error!”));

}else{

MessageBox(_T(“saveSettings Success!”));

}

}

 

void CUpdateIpDlg::initSettings(){

m_strSettingFilepath = getSettingFilePath();

m_bAutoStart = (BOOL)GetPrivateProfileInt(_T(“config”),_T(“autostart”),1,m_strSettingFilepath);

m_nUpdateInterval = GetPrivateProfileInt(_T(“config”),_T(“updateinterval”),c_nDefaultUpdate,m_strSettingFilepath);

 

((CButton *)GetDlgItem(IDC_CHECK_AUTOSTART))->SetCheck(m_bAutoStart);

if (!setAutoStart(m_bAutoStart))

{

MessageBox(_T(“setAutoStarterror”));

}

 

SetDlgItemInt(IDC_EDIT_UPDATEINTERVAL,m_nUpdateInterval);

}

 

BOOL CUpdateIpDlg::saveSettings(){

CString strTemp;

strTemp.Format(_T(“%d”),m_bAutoStart);

if (!WritePrivateProfileString(_T(“config”),_T(“autostart”),strTemp,m_strSettingFilepath))

{

return FALSE;

}

 

strTemp.Format(_T(“%d”), m_nUpdateInterval);

if (!WritePrivateProfileString(_T(“config”),_T(“updateinterval”),strTemp,m_strSettingFilepath))

{

return FALSE;

}

 

return TRUE;

}

 

CString CUpdateIpDlg::getSettingFilePath(){

TCHAR szPath[MAX_PATH] = {0};

BOOL bRet = SHGetSpecialFolderPath(NULL,szPath,CSIDL_APPDATA,FALSE);

if (!bRet)

{

MessageBox(_T(“SHGetSpecialFolderPath Failed!”));

return _T(“”);

}

 

CString strFolder = szPath;

strFolder += “\\autoupdateip\\“;

if (!CreateDirectory(strFolder,NULL) && GetLastError() != ERROR_ALREADY_EXISTS)

{

MessageBox(_T(“创建临时目录失败!”));

return _T(“”);

}

 

return strFolder + c_szSettingFilename;

 

}

 

LRESULT CUpdateIpDlg::OnNotifyIcon(WPARAM wParam,LPARAM IParam)

{

if ((IParam == WM_LBUTTONDOWN) || (IParam == WM_RBUTTONDOWN))

{

ModifyStyleEx(0,WS_EX_TOPMOST);

ShowWindow(SW_RESTORE);

//Shell_NotifyIcon(NIM_DELETE, &NotifyIcon);

}

 

return 0;

}

 

void CUpdateIpDlg::addNotification(){

NotifyIcon.cbSize=sizeof(NOTIFYICONDATA);

NotifyIcon.hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);

NotifyIcon.hWnd=m_hWnd;

lstrcpy(NotifyIcon.szTip,_T(“Auto Update IP by weibin”));

NotifyIcon.uCallbackMessage=WM_NC;

NotifyIcon.uFlags=NIF_ICON | NIF_MESSAGE | NIF_TIP;

Shell_NotifyIcon(NIM_ADD,&NotifyIcon);

}

 

 

通过admin

Ubuntu server10.4实现自动登录

下面是网上找的方法:

 

注意:这里的修改要非常小心,出来命令不能敲错之外,一定要记得执行chmod +x autologin,不然搞不好可能会导致启动不了,我在操作的时候就因为忘了执行chmod +x autologin,导致系统一直启动不起来,最后只能通过其他引导系统,并且改回原先的配置(我用的是recovery进入系统,可以直接执行chmod +x autologin)。

 

一、写脚本autologin

代码:

#!/bin/bash

/bin/login -f <username> #你的用户名

 

chmod +x autologin设置可执行权限,移动到/usr/bin/下。

 

二、把/etc/event.d/tty1中下面这一行:

代码:

exec /sbin/getty 38400 tty1

修改为

代码:

exec /sbin/getty -n -l /usr/bin/autologin 38400 tty1

 

现在已经实现自动登录,下面使自动启动X。

 

三、修改.profile使登录后直接进入X

 

添加:

代码:

if [ -z “$DISPLAY” ] && [ $(tty) == /dev/tty1 ]; then

startx

fi

 

四、重启。成功。

 

通过admin

利用ctags,实现应用库函数的跳转

首先安装ctags,安装过程网上很多,就不多讲,安装之后执行ctags -R,就可以在本项目内实现代码跳转了,但不能跳转到不是在本项目的代码中定义的tag。例如在上面的图中,本地定义了一个类A,在main函数中定义了一个A类的对象,我们可以按“Ctrl+]”组合键跳转到class A那一行。然后可以按“Ctrl+O”跳转回来。

如果想实现跳转到非本项目的tag,则必须让Vim知道这些tag在哪。刚才的项目在/home/user/code/目录下,现在假设又有一个项目在/home/user/program/下,那么我们需要在此项目下生成program这个项目的tags文件(还是用上面的ctags命令)。

生成之后,要告知Vim,需要在Vim的配置文件中(/home/user/.vimrc)添加下面的内容:

” — ctags setting —
set tags=tags
set tags+=./tags        ” add current directory’s generated tags file
set tags+=~/program/tags ” add new tags file

最后一行就表示在搜寻tags文件的时候,也要搜寻/home/user/program/文件夹下的tags文件。保存以后重启,此时应该就能实现不同项目间的跳转了。这是因为我们经常会基于一些库开发软件,我们需要查看库中函数或者类的定义的时候,会经常需要此功能。

 

 

例如最近在用的protobuf库,首先进入到该库的代码路径:cd /home/user/protobuf2.41

,执行ctags -R,生成tags,然后编辑sudo vim /etc/vim/vimrc,在末尾添加:

” — ctags setting —
set tags=tags
set tags+=./tags        ” add current directory’s generated tags file
set tags+=~/protobuf2.41 ” add new tags file

 

重新打开vim,就发现以前跳转不过去的函数现在也可以跳转了。在vim的命令行状态也可以执行:set tags+=~/protobuf2.41临时加载一个tags,但是只在本次有效。

通过admin

linux中man用法

Linux中的man是按照章节和档案名字来编排的,man的格式是:

Man [章节] [档案名字]

例如要查询系统调用connect函数的帮助,则可以用:man  2 connect;

查看C库函数printf:man 3 printf

在C/C++编程中如果想知道一个函数的用法和声明头文件,则可以通过man来查看 。

 

具体章节:

编号 代表內容
1 使用者在shell中可以操作的指令或可执行档
2 系統核心可呼叫的函数与工具等
3 一些常用的函数(function)与函数库(library),大部分是C的函数库(libc)
4 装置档案的说明,通常在/dev下的档案
5 设定档或者是某些档案的格式
6 游戏(games)
7 惯例与协定等,例如Linux档案系统、网络协定、ASCII code等等的說明
8 系統管理員可用的管理指令
9 跟kernel有关的文件
通过admin

跟我一起写 Makefile

概述

——

什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些 Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要了解HTML的标识的含义。特别在Unix下的软件编译,你就不能不自己写makefile 了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。

因为,makefile关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。

makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。

现在讲述如何写makefile的文章比较少,这是我想写这篇文章的原因。当然,不同产商的 make各不相同,也有不同的语法,但其本质都是在“文件依赖性”上做文章,这里,我仅对GNU的make进行讲述,我的环境是RedHat Linux 8.0,make的版本是3.80。必竟,这个make是应用最为广泛的,也是用得最多的。而且其还是最遵循于IEEE 1003.2-1992 标准的(POSIX.2)。

在这篇文档中,将以C/C++的源码作为我们基础,所以必然涉及一些关于C/C++的编译的知识,相关于这方面的内容,还请各位查看相关的编译器的文档。这里所默认的编译器是UNIX下的GCC和CC。

 

关于程序的编译和链接

——————————

在此,我想多说关于程序编译的一些规范和方法,一般来说,无论是C、C++、还是pas,首先要把源文件编译成中间代码文件,在Windows下也就是 .obj 文件,UNIX下是 .o 文件,即 Object File,这个动作叫做编译(compile)。然后再把大量的Object File合成执行文件,这个动作叫作链接(link)。

编译时,编译器需要的是语法的正确,函数与变量的声明的正确。对于后者,通常是你需要告诉编译器头文件的所在位置(头文件中应该只是声明,而定义应该放在C/C++文件中),只要所有的语法正确,编译器就可以编译出中间目标文件。一般来说,每个源文件都应该对应于一个中间目标文件(O文件或是OBJ文件)。

链接时,主要是链接函数和全局变量,所以,我们可以使用这些中间目标文件(O文件或是OBJ文件)来链接我们的应用程序。链接器并不管函数所在的源文件,只管函数的中间目标文件(Object File),在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以,我们要给中间目标文件打个包,在Windows下这种包叫“库文件”(Library File),也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件。

总结一下,源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译时,编译器只检测程序语法,和函数、变量是否被声明。如果函数未被声明,编译器会给出一个警告,但可以生成Object File。而在链接程序时,链接器会在所有的Object File中找寻函数的实现,如果找不到,那到就会报链接错误码(Linker Error),在VC下,这种错误一般是:Link 2001错误,意思说是说,链接器未能找到函数的实现。你需要指定函数的Object File.

好,言归正传,GNU的make有许多的内容,闲言少叙,还是让我们开始吧。

 

Makefile 介绍

———————

make命令执行时,需要一个 Makefile 文件,以告诉make命令需要怎么样的去编译和链接程序。

首先,我们用一个示例来说明Makefile的书写规则。以便给大家一个感兴认识。这个示例来源于GNU的make使用手册,在这个示例中,我们的工程有8个C文件,和3个头文件,我们要写一个Makefile来告诉make命令如何编译和链接这几个文件。我们的规则是:

1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。

2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。

3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。

只要我们的Makefile写得够好,所有的这一切,我们只用一个make命令就可以完成,make命令会自动智能地根据当前的文件修改的情况来确定哪些文件需要重编译,从而自己编译所需要的文件和链接目标程序。

 

一、Makefile的规则

在讲述这个Makefile之前,还是让我们先来粗略地看一看Makefile的规则。

target … : prerequisites …

command

target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。

prerequisites就是,要生成那个target所需要的文件或是目标。

command也就是make需要执行的命令。(任意的Shell命令)

这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于 prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比 target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。

说到底,Makefile的东西就是这样一点,好像我的这篇文档也该结束了。呵呵。还不尽然,这是Makefile的主线和核心,但要写好一个Makefile还不够,我会以后面一点一点地结合我的工作经验给你慢慢到来。内容还多着呢。:)

 

二、一个示例

正如前面所说的,如果一个工程有3个头文件,和8个C文件,我们为了完成前面所述的那三个规则,我们的Makefile应该是下面的这个样子的。

edit : main.o kbd.o command.o display.o /

insert.o search.o files.o utils.o

cc -o edit main.o kbd.o command.o display.o /

insert.o search.o files.o utils.o

main.o : main.c defs.h

cc -c main.c

kbd.o : kbd.c defs.h command.h

cc -c kbd.c

command.o : command.c defs.h command.h

cc -c command.c

display.o : display.c defs.h buffer.h

cc -c display.c

insert.o : insert.c defs.h buffer.h

cc -c insert.c

search.o : search.c defs.h buffer.h

cc -c search.c

files.o : files.c defs.h buffer.h command.h

cc -c files.c

utils.o : utils.c defs.h

cc -c utils.c

clean :

rm edit main.o kbd.o command.o display.o /

insert.o search.o files.o utils.o

反斜杠(/)是换行符的意思。这样比较便于Makefile的易读。我们可以把这个内容保存在文件为“Makefile”或“makefile”的文件中,然后在该目录下直接输入命令“make”就可以生成执行文件edit。如果要删除执行文件和所有的中间目标文件,那么,只要简单地执行一下“make clean”就可以了。

在这个makefile中,目标文件(target)包含:执行文件edit和中间目标文件(*.o),依赖文件(prerequisites)就是冒号后面的那些 .c 文件和 .h文件。每一个 .o 文件都有一组依赖文件,而这些 .o 文件又是执行文件 edit 的依赖文件。依赖关系的实质上就是说明了目标文件是由哪些文件生成的,换言之,目标文件是哪些文件更新的。

在定义好依赖关系后,后续的那一行定义了如何生成目标文件的操作系统命令,一定要以一个Tab 键作为开头。记住,make并不管命令是怎么工作的,他只管执行所定义的命令。make会比较targets文件和prerequisites文件的修改日期,如果prerequisites文件的日期要比targets文件的日期要新,或者target不存在的话,那么,make就会执行后续定义的命令。

这里要说明一点的是,clean不是一个文件,它只不过是一个动作名字,有点像C语言中的 lable一样,其冒号后什么也没有,那么,make就不会自动去找文件的依赖性,也就不会自动执行其后所定义的命令。要执行其后的命令,就要在make 命令后明显得指出这个lable的名字。这样的方法非常有用,我们可以在一个makefile中定义不用的编译或是和编译无关的命令,比如程序的打包,程序的备份,等等。

 

源文档 <http://blog.csdn.net/haoel/article/details/2886>

 

通过admin

linux下Google的Protobuf安装及使用笔记

protobuf

项目主页:http://code.google.com/p/protobuf/

下载:http://code.google.com/p/protobuf/downloads/list protobuf-2.4.1.tar.gz

解压后进入protobuf-2.4.1目录进行安装:

1、./configure(注:默认可能会安装在/usr/local目录下,可以加–prefix=/usr来指定安装到/usr/lib下,可以免去路径的设置,路径设置见Linux命令pkg-config

./configure –prefix=/usr/local/protobuf

2、make

3、make check

4、make install(需要超级用户root权限)

二、使用

1、写proto文件,定义消息具体格式。如:helloworld.proto

package lm;

message helloworld

{

required int32 id = 1;//ID

required string str = 2;//str

optional int32 opt = 3;//optional field

}

2、使用protoc来编译生成对应语言的文件

–cpp_out:表示输出c++语言使用格式,–java_out,–python_out等,其他第三方的插件:Third-Party Add-ons for Protocol Buffers

此时会生成helloworld.pb.h及helloworld.pb.cc两个文件

3、Write A message

View Code

4、Read A message

View Code

5、编译及运行

g++ -g -o Writer helloworld.pb.cc writermessage.cpp `pkg-config –cflags –libs protobuf`

g++ -g -o Reader helloworld.pb.cc Readermessage.cpp `pkg-config –cflags –libs protobuf`