2013年2月28日星期四

PzEA – 月付6.47美金的Psychz 512M XEN性能简单测试


PzEA
PzEA是一家新上线的面向国际市场的VPS服务商,产品主要基于XEN架构,提供洛杉矶WebNX,Psychz以及圣何塞三个均十分优秀的机房.新近拿到一个Psychz机房512M做了一些简单测试..通过这个测试,也基本能够了解到服务器的硬件性能和网络环境.
废话不多说,还是来看看这款VPS的基本情况吧:
512M独立内存,2个CPU核心,20G RAID 10硬盘,1个IP,百M网络,月流量500G.
这个配置能够满足绝大部分中小网站的使用.官方价格月付9.95美元,使用65折优惠码:heitao,终身月付仅需:6.47美元(约合人民币:40.3元,价格十分诱人),另外需要特别提到,PzEA只支持PayPal支付.最后发一下购买链接:点我购买,感谢支持我的朋友.
好了,接下来是正题,贴一下我测试的结果截图.
首先是CPU的基本信息:
cpu
处理器采用了E3-1230,512M款使用2核心,.256M款使用1核心,1G款使用4核心,2G款则使用6核心.

然后是硬盘测试:
DD
硬盘使用了RAID 10技术,笔者通过5次连续的DD测试,得出硬盘的IO性能处于平均89M的水平,这个结果也仅仅代表笔者测试的时间得出的结果,如果你在一个不同的时间测试,也能够得出更高的结果.我只说80+M这个水平,用来做网站真的非常优秀.

再然后是网络测试:
net
同样是5次下载测试,每秒10+M的下载速率,标准的百M网络端口.做站同样优秀.

再来的就是UB测试了:
UB1UB2
1核心得分679,表现不错.2个核心得分1088.相当给力..

最后来的是Ping测试:
Ping1
Ping2
中国大陆访问Psychz机房还是很不错的..最快可到147ms(浙江宁波电信)

好了,这就是这款512M XEN的简单测试了.对于建设小网站的其他微小应用的朋友,则可以购买256M的配置,256M足以满足小型网站的基本建站需求.但是对于一些处于发展期或者是架设一些大型应用程序的朋友,还是推荐购买512M以上的配置,这是为了避免出现性能瓶颈.
512M的配置使用优惠码:heitao,月付也仅需6.47美元,在月付10美元以下的低端VPS中,不仅价格非常非常不错,性能也是非常优秀的.

IOS6设备完美越狱 iPad mini/iPad3实战


在万众期待之下,iOS6.1的完美越狱终于赶在中国新年之前放出了,这真是献给中国果粉最好的新年礼物了。此次iOS6.X越狱可谓历经波折,从最开始的无从下手,到期间和苹果斗智斗勇,到最后的柳暗花明,中间还穿插着越狱“大婶们”关于越狱是否该收费的讨论。不管过程如何艰难,总归越狱还是来了。

iOS6平板完美越狱 iPad mini/iPad3实战
▲evasi0n越狱官网
首先请熟读以下越狱须知:
  此次越狱支持固件版本从iOS6.0~iOS6.1之间的iOS设备,具体产品列表见本页末尾。
  此次越狱工具支持:Windows、Mac、Linux三个平台,其中Windows最低支持XP版本,Mac最低支持10.5版本。
  此次越狱工具下载:
  Windows版本工具官网下载点击这里国内网盘下载地址点击这里。
  Mac版本工具官网下载点击这里国内网盘下载地址点击这里。
  Linux版本工具官网下载点击这里国内网盘下载地址点击这里。
  越狱方法:文章这里照顾大多数人设备,仅提供Windows版越狱教程。
  关于越狱:iPad及iPad mini所使用的是苹果独家的iOS操作系统,iPad的iOS与其他平板系统(如谷歌Android最大的不同是:后者用户权限较高,而iOS用户权限极低。因此iOS的用户只能使用经过苹果验证(Apple Store中购买的)的应用程序,并且也无法对系统本身进行更改。
  而越狱后,使得用户拥有可以读写系统文件的权限,可以安装和运行未经过官方认证的第三方程序,甚至是改变系统文件等等。在国内典型的应用包括可以安装各种插件,如第三方输入法,上网防火墙等等。
  在越狱前请先确认你的设备是否在支持越狱的设备列表:
  本次越狱支持设备:(需运行iOS 6.0至6.1的系统,不兼容iOS 5等旧版系统)
  iPhone 3GS、iPhone 4、iPhone 4S、iPhone 5
  iPad 2、the new iPad (iPad 3)、iPad 4、iPad mini
  iPod touch 4、iPad touch 5
  如果你的设备在列表中,但是系统版本并非6.X,那么请先升级系统,然后再进行越狱操作,相关越狱教程请看下一页。

  越狱步骤详解
  准备工作:
  Windows操作系统电脑一台(至少是XP)或Mac电脑(OS 10.5以上)或Linux操作系统电脑(32位/64位系统皆可),去官方官网下载对应操作系统的版本。
  本教程只适用于Windows操作系统。
  在越狱之前需要注意到事项,请大家务必仔细阅览:
  1、在使用evasi0n越狱工具前请使用iTunes或者iCloud备份iOS设备的数据(前提是电脑已经安装过iTunes),以免在越狱过程中碰到意外情况,即便是导致越狱失败,也能够确保你的数据不会丢失。备份手机可以连接iTunes选择备份到本地/iCloud即可。
  2、在使用evasi0n时,请关闭锁屏密码。锁屏密码会导致一些意外发生。如果没有设置密码的最好,此前设置过锁屏密码的可以通过以下方式关闭。关闭锁屏密码的方式为设置-通知-密码锁定-关闭密码。
  3、由于越狱需要一定时间,在越狱过程中请保持耐心,不要启动iTunes(Mac系统不要启动Xcode)。最好的方法就是:在越狱完成之前,不要去碰电脑,让手机自己操作。
  4、如果越狱过程中电脑卡顿导致无响应,可以尝试关闭,然后再次打开。越狱程序是安全的,并不会影响到你的手机和电脑,建议可以同时启动手机和电脑。
越狱步骤详解
▲本次待越狱的两个平板:iPad mini和iPad3,系统版本分别为iOS 6.0.2和6.1
注意好以上事项后就可以开始越狱了,步骤如下:
  1、下载文件,解压缩后打开越狱主程序evasi0n,将待越狱平板接入电脑,此时evasi0n应该会检测到你的设备以及系统版本并显示,此时可点击Jailbreak按钮,越狱开始运行。
越狱步骤详解
▲越狱程序检测到iPad mini,表示可以越狱
2、按下按钮后程序会自动进行越狱的全部流程,越狱过程中最好不要用手触摸屏幕,也不要在电脑上做其他操作,你要做的只是耐心等待。
  方法很简单 iOS6.1完美越狱教程方法很简单 iOS6.1完美越狱教程
  方法很简单 iOS6.1完美越狱教程方法很简单 iOS6.1完美越狱教程
  3、程序到关键步骤时,越狱工具的界面将会出现一段特别长的英文(如下图),同时平板内自动生成一个“jailbreak"的应用图标,我们此时进入平板点一下这个图标,会出现一闪而退的情况,属于正常现象。点击过后程序窗口继续进行越狱。
越狱步骤详解
▲进行到一定进度,进度条上方会出现一段文字在闪烁
越狱步骤详解
▲平板上会出现一个图标,只要点击一下这个图标即可
4、程序窗口大约继续1分钟后提示越狱成功,此时手机重启进入自动越狱状态,画面出现JailBreak的提示,需要特别说明的是,这个过程需要3-5分钟,不是死机也不是失败,耐心等候即可。笔者发现如果是手机越狱的话这个过程很漫长,iPad的话会比较快,这两台平板都不到一分钟就结束了。
  方法很简单 iOS6.1完美越狱教程方法很简单 iOS6.1完美越狱教程
越狱步骤详解
▲出现这个画面表示即将成功
5、等待后平板自动重启,进入程序菜单,看见熟悉的Cydia!OK,越狱成功。
越狱步骤详解
▲看到如图的Cydia图标即代表越狱成功
越狱步骤详解
▲两台iPad都成功越狱!
越狱后注意事项:
  由于目前众多插件还尚未支持iOS 6,请勿随意安装插件和输入法,以免造成冲突导致无法开机或者开机白苹果。(目前已经接到不少网友反应安装输入法造成无法开机)
越狱步骤详解
▲插件勿乱装以免引冲突
第三方插件目前需要一段时间来兼容iOS 6.0和6.1,暂时不建议安装插件,建议等待后续网络分享的兼容报告后再进行安装。
  请随时备份重要数据,以免因为越狱带来的不可控风险导致重要数据丢失。
  越狱将会导致你的设备无法享受苹果官方的正常保修,如果近期有打算去苹果零售店进行维修的网友,请勿进行越狱,如果是已经越狱过的,可以通过恢复方法重新刷回原始状态。
  以上越狱教程,同样适用于iPhone手机。

番号解码:数字背后的中国军队血脉谱系


资料来源:人民网、环球网。
  2013年1月15日晚,中央电视台新闻频道播出的一则军事报道中,使用了“39集团军”的说法,而非之前常用的“某部队”。随后,央视新闻频道官方微博发布消息:“我军陆军集团军番号今起解密。”
  番号,是一种既神秘又熟悉的数字。“八路军”中的“8”,“新四军”中的“4”,其实都是番号。但如今,于普通人而言,大部分番号又的确属于保密范畴之内。
  外界大部分评论认为解密集团军番号是解放军走向公开透明的动作之一。不过,从番号这组难以磨灭的数字中,更能解码中国军队几十年发展历程的血脉谱系,甚至触摸代代相传的情感脉络。
  非连续数字组成解放军DNA
  包括39集团军在内,此次被解密的陆军集团军番号共有18个,最小的是1,最大的是65.这18个番号中,有的是连续的,例如12、13、14;更多的则不连续,例如31之后便是38,54之后便是65.
  实际上,解放军陆军番号最大的数字曾经达到70。
  这些近似于随机出现的空白,并不是在编制番号时人为制造的——正是这断续的数字和数字之间的空白,成为记载解放军发展史的DNA.
  1948年9月,中共中央在西柏坡召开政治局扩大会议,毛泽东提出人民解放军要“有计划地走向正规化”。会后,周恩来开始负责拟订全军编制方案的工作。
  很快,中央军委做出《关于建军方针及部队编制等问题的决定》,指出“我正规军须要发展至210个步兵师,编组为20个兵团,70个军”。11月1日,中央军委发出《关于统一全军组织及部队番号的规定》,第一次在全军范围内统一了番号。
  这次统一番号,亦遵循了一定的规律,这种规律让熟稔军队历史的人,得以很快判断出每一个数字背后的血脉关系。
  “这70个军的整编,一般遵循了‘三三制’的规则,也即:一个野战军三个兵团,一个兵团三个纵队,一个纵队就对应了一个军。”《军营文化天地》杂志主编、战史作家余戈对南方周末记者说,“这样一来,10以前的军基本脱胎自第一野战军,10-20之间的军基本来自第二野战军,依此类推,四野之后是华北军区的纵队。”
  这样的“三三制”对应关系并不十分精确,一个重要的原因是:其中一些番号给了国民党起义部队。例如,第9军就是由在新疆起义的国民党军整编第42师改编而成的,第36军则是改编自绥远起义的国民党军一部。
  此番在央视露脸的39集团军驻扎在辽宁沈阳。内行的军迷可以根据“39”这个数字很快大致推断出:它的血脉应来自第四野战军——的确,39军的前身正是第四野战军(即东北野战军)第2纵队,这支纵队在中央军委发出统一番号通知的当天,就改称为39军。
  比较特殊的是,在这70个番号中,有3个从未使用过,它们是:56、57和59.关于它们未曾使用的原因,官方战史中未见详细解读。
  另一个有趣的现象是:除去从未使用的3个番号,解放军历史上先后有过67个军,最多时有62个军共存,但这67个军却只有66位首任军长——番号最大的第70军没有首任军长。
  根据军史研究者叶青松的考证,这是因为70军在尚未配上军长的时候,番号就被撤销了。被撤销的原因,则是聂荣臻、薄一波和唐延杰在1949年9月提出的建议:“七十军为紧缩机构便于整训,提议将该军缩编为一个师,我们同意(现该军辖两个师共11916人,每连不满百人)。拟将军直改为师的直属架子,所属两个师直的勤杂人员可充实连内,而干部除另外分配外可入军大学习。”
  新中国成立后,解放军进行过几次大规模的精简整编,先后有近50个番号被撤销。正是这些举措,使得番号之间留下了空白。
  新中国成立初期的3次大规模精简整编,将三十余个军番号送进了历史档案。这些被撤销的军,有的调入了海军、空军部队,例如曾在朝鲜战场上做出重要贡献和重大牺牲,诞生了黄继光、邱少云的第15军,在1961年被改编为空降兵,这被普遍视为一种莫大的荣誉和馈赠;有的改为了地方军区,例如第19军军部改编为陕西军区;还有的集体转业到地方从事经济建设,例如前述由起义部队改编的第9军,就有3个师依次改编为新疆农业建设兵团第7、第8、第9师,成为一支有组织、有训练的产业大军。
  改革开放后,番号最重要的一次变化出现在1985年的百万大裁军中。当时,陆军的35个军按照“去新留老”的基本原则,撤销了11个军的番号。保留的24个军则全部组建为合成集团军,其中2个为机械化集团军。
  其后,在1997年和2003年的两次裁军中,番号又被裁撤了6个,总数变成了今天的18.
  可见,从没有统一正规编制的部队到统一命名的70个军,再从70个军到18个集团军的演变史,就是一部微缩的解放军发展史。手握这套密码,既可以向前追溯至抗日战争和解放战争年代,又可以借以回顾新时期的几次裁军。

中央电视台首次在新闻中公开集团军番号,不再以“某”替代。 (央视新闻截图)
  台湾没有8路公交车?
  如果仅仅将解放军的番号视为记录历史沿革的一串数字工具,那就小看了时间的力量。经过岁月的酿造之后,这些普通甚至枯燥的数字竟具有了特殊而醇厚的感情色彩。
  在大陆,很长时间内都流传着一种说法:台湾没有8路公交车,因为蒋家对八路军心怀恐惧,害怕“8”这个数字。这样的说法甚至还发展成了一些栩栩如生的传说,虽然这些传说后来被台湾当地人证伪。
  更多时候,番号的数字不是人们恐惧的对象,而是军人寄托回忆、感情,乃至“迷信”的对象。
  党史上最早、最著名的一次“番号迷信”,发生在1928年4月。当时,在著名的井冈山会师之后,中共成立了第一支以“红军”命名的队伍,但是,这第一支队伍的番号却不是“1”,而是“4”,即红军第四军。
  后来在接受美国人埃德加·斯诺的采访时,朱德解释了选择“4”这个数字的原委:“要保持国民革命军第四军‘铁军’的大名,它在大革命中是我们革命的堡垒。”
  据专家研究,“八一三事变”后,叶挺向蒋介石提出为了抵抗日本侵略,“让我来集合仍留在南方的红军和改编这些军队”的建议,并说改编后番号叫“新四军”。蒋介石接受了叶挺的建议,番号则得到了国共两党的认可。蒋介石认可“新四军”,是他任总司令的北伐军中有个第四军。毛泽东认可“新四军”,是他创建人民军队的第一个军是红四军。
  原来,第一次国共合作北伐,北伐的8个军中第四军共产党员最多、战斗力最强。由著名将领张发奎率领的国民革命军第四军是第一次国共合作时的北伐铁军,而其中以共产党骨干组成的“叶挺独立团”又是这支铁军的前锋。于是,“4”成为共产党军队格外看重的一个数字。
  “在战争年代,番号往往成为一种带有感情色彩,乃至某种神秘主义的东西。”余戈说。
  1949年之后,虽然国内再也没有大规模的战争爆发,但番号承载的情感意义却丝毫没有减弱。一方面,战争年代的故事随着番号代代流传;另一方面,新中国成立后若干次小规模的出国作战,以及不断换防、裁撤、合并的经历,又在继续赋予番号独特的意义。
  “如今去部队参观,基本都可以在军史馆、师史馆里看到一张谱系表和一张转战图。”余戈说。谱系表就是这支部队的“家谱”,它是一张记录了血脉传承关系的图表,从中可以读到番号流转的过程。而转战图则从地理的角度记录了这支部队的历史,一般是一张中国地图,并显示出邻国朝鲜、越南,用红色的箭头在图上标注出转战的经历。
  正因为数字成为血脉谱系中的重要依据,因此,在一轮轮的裁撤和合并过程中,每一支部队都希望留下自己的番号,不想让这个数字的历史终结。
  在番号裁撤的选择之中,不同部队之间的强弱关系便显示出来了。“如果番号背后的军队实力强大,那么就很难被裁掉。林彪昔日的部队战功卓著,因此第四野战军(东北野战军)留下的番号最多,至今仍有7个存在。”余戈说。
  如果被裁撤的部队实力相当,那么就需要一些其他的解决方法。一个有趣的例子是第54军,它由原第45军和原第44军合并而来。根据一些老战士的口述,这两支部队都想保留自己的番号,最后是周恩来出面才得以“摆平”——他说服双方都各保留一个数字,最终合并成了54军。
  另一个特殊的例子是有“济南第一团”之称的235团。在1998年的“师改旅”当中,它由陆军第27集团军第79师第235团改为了陆军第27集团军第235旅——可以看到,团的番号保住了,师的番号则消失了,这是非常罕见的现象。对于这个团来说,这是莫大的荣誉,因为这个番号的历史可以续写下去;而相应地,79师的番号则终结了发展历程。
  “一个部队的历史就像一个新兵的成长史,如果衣服都没洗白过,那就没价值。洗得越白,越有补丁,说明你越有资历。”余戈说,“无论哪个领导,去了一支部队后如果看到那些有历史的番号,怎么都得高看一眼,感情上都会更加接近。而一个新兵进了一个有光辉战史的部队,在特殊的番号光环之下,也无形之中会对自己提出更高的要求。”
  走向公开透明,但限定范围
  虽然军人们将番号视为凝结了历史与感情的数字,但这些数字的意义一般仅限于军队内部分享。
  出于保密的需要,在对外场合中,军队都使用着另一套被称为“代号”的系统。部队代号是由总部统一编拟、授予和管理的,一般授予团以上的部队以及需要保密的军事单位。在承办公文时,部队代号与部队番号具有同等效力。
  使用“代号”这套系统,是受到了日本人的启发——日本军队的称呼有几套系统,内部使用的是番号,对外使用的则一般有两种,一种是用部队长官的姓氏,另一种就是数字编码。不同之处在于,日本军队的数字编码前会有一个汉字,这些汉字经过了精心选择,例如“龙6734部队”。
  而在解放军部队中,这些代号一般是5个阿拉伯数字组成。战士在与家人通信时,也都使用“××省××市×××××部队”这样的地址格式。
  另一个频繁使用代号的场合便是公开的新闻报道。涉及军队的报道稿件在发表之前都会经过脱密处理,而番号正是在脱密过程中被统一隐去,改为“某部队”的泛泛称呼。
  不过,在信息化战争时期,解放军的集团军番号实际上早已是公开的秘密。在维基百科上,18个集团军的条目可以任意查阅。比之更甚的,是一个叫做“SinoDefence”的英国网站。在这个由志趣相投的志愿者创建的网站上,有对各集团军的详尽介绍,包括历史沿革、历任将领、参战历史、驻地、装备等方方面面的信息。
  至于美国五角大楼每年发布的中国军力报告,更是对解放军有着深入的研究。
  “将陆军集团军的番号公开,是近年来中国军队不断走向公开透明的一系列举措中的一个动作。”《世界军事》杂志主编陈虎对南方周末记者说。
  在他看来,解放军公开番号和及时发布辽宁号航母、歼-15、运-20的消息一样,都是对外界关注的主动回应。
  实际上,将一些有影响力的番号解密,也不失为一种国防教育的方式。例如,美军的精锐部队82空降师、101空降师,以及俄罗斯的“塔曼师”等,早已是家喻户晓乃至名扬海外的名称。
  不过,陈虎同时强调,这一次的番号解密属于有限定范围的公开,师、团级别的部队番号就不属于公开范围。
  另一方面,番号解密了,也不代表集团军的其他信息就可以公之于众。根据《保密条例》的要求,被解密番号的第39集团军,其部队任务、实力、状态等情况中需要控制知悉范围的事项和军事部署、作战、训练以及处置突发事件等军事行动中需要控制知悉范围的事项,仍然需要保密。
  “美军的作战报道中,即便是嵌入式的深度报道,也有很多信息是不公开的,例如海湾战争中第几师部署在哪,这是不会公开的。”陈虎说,“所以,公开都是相对的,前提是不能影响国防安全和作战保密。”
  解放军在番号上公开透明的脚步会继续走到哪一步,尚待观察。可以肯定的是,即便这些数字完全公开,番号这组密码背后的血脉与感情也是外人永远无法完全真切感受和分享的。

齐景公为什么不敢“平坟”?



日期:[2012年12月23日]  版次:[AA26]  版名:[历史评论]  稿源:[南方都市报]  

    □狄马 知名作家

    《晏子春秋》中讲了这样一个故事:齐景公的办公大楼“路寝之台”建成后,有个叫逢于何的人母亲死了。在路上碰见晏子,就给晏子行大礼。晏子问:“我能为你做什么呢?”逢于何说:“我的母亲去世了,而父亲的墓就在路寝之台的内墙下,我希望把他们合葬在一起。”晏子听了很为难,但还是答应给景公带话。虽然不免有些担心地问,万一不成,你怎办啊?逢于何回答说:“有权有势的人当然有办法,但像我这样的小人物,如果得不到允许,我将左手拉住灵车的辕木,右手捶打着自己的胸口,站在这里挨饿而死,以此告诉四方之人:我逢于何是个不能安葬自己母亲的人!”换成现在的话说,就是:逢于何的要求如果得不到满足,他就到政府门前上访,上访不成,他就在这里绝食而亡。

    晏子进去后,就把事情给景公说了。景公气得脸都白了,说:“从古到今,你听说过把死人埋在国君宫殿内的吗?”这时,晏子作为一个政治家的风骨就显露出来了。他说:“古代的君王,他们的宫殿建得很节制,不侵占活人的房子;他们的楼台很简朴,不侵占死人的墓地,所以,当然没听说过要到国君的宫殿内埋人的事。但您现在大规模修建宫殿,侵占活人的房子;广修楼台馆所,剥夺死人的墓地。使活着的人忧愁,不能安居;让死去的人分离,不得合葬。尽情享乐游玩,对生者死者都亵慢无礼,不是仁德之君的作为;只顾满足自己的欲望要求,不管百姓的死活,不是保存国家的正道。而且晏婴听说:活着的人不得安居,叫蓄忧;死去的人不得安葬,叫蓄哀。蓄忧招致怨恨,蓄哀导致危险,你还是答应了吧!”

    晏子出去后,一个叫梁丘据的大臣对景公说:“从古到今,没听说过到王宫埋人的,你怎么答应了?”景公说:“推平人家的房子,祸害人家的墓地,羞辱人家的葬礼,还不许人家安葬亲人,这是对活人刻薄寡恩,对死人傲慢无礼。《诗经》中说:‘榖则异室,死则同穴。’我敢不答应吗?”逢于何于是把母亲葬在了路寝之台下。只是没有穿孝服,没有嚎啕大哭,进行完基本的仪式后,就流着眼泪离开了。

    这是发生在春秋末期的事。它告诉人们,一种信仰或观念是几代、甚至几十代人根据他们所处的环境、所能利用的材料自发习得的结果,即使是那些手握生杀大权的君王也不能随意颠覆。我们所能做到的,仅仅是把其中一部分不合理的,不适应世界潮流的观念、习俗根据变化了的现实作出修订——— 比如当今世界普遍推行的自由价值和法治观念,就是这样一种大势所趋人心所向的原则。但在修订之前,我们得先分清,传统中的哪些价值是妨碍我们走向民主自由的,哪些价值是可以与宪政文明并行不悖的,而哪些价值是打着现代化的幌子,实际是要摧毁现存的一切文明规则,让我们彻底回到野蛮人的生存状态里的。

    就我自己而言,我觉得传统本身是一个很复杂的体系,其中有的门类受意识形态(在古代中国,主要指的是以三纲五常、忠孝节义为核心的一整套关于国家、社会、政治、经济的基础理论和教条)的影响很大,比如传统的政教、律令、哲学、道德就因为皇权专制的直接需要,几乎完全被意识形态化了。即使是那些讲无为、任自然的,也散发着一种冷血的气息。有的门类则由于性质上离皇权较远,皇帝和他的官僚系统即使需要它为专制服务,也不是直接的,因而意识形态的色彩较淡,反而保留了一种人的气息、自由的特质,比如古典的诗词、绘画、音乐、舞蹈、建筑、医学等。对于前者,由于它与现代文明格格不入,我们当然要抛弃;对于后者则不妨存留,慢慢赏析。

2013年2月27日星期三

如何用 Private Tunnel 上网



Private Tunnel 是一款由 OpenVPN 官方推出的 OpenVPN 服务,有免费的,也有付费的,其中免费的流量为 100 MB, 付费的流量根据价格的不同而不同。
Private Tunnel
除了流量之外,不管是免费的还是付费的,Private Tunnel 所提供的服务都是一样的。

一、Private Tunnel 的优势

相对其他免费 VPN 而言,Private Tunnel 具有以下三个优势:
1、你可以选择不同的服务器
Private Tunnel 提供以下三个不同的服务器供选择:
  • San Jose, CA (US),
  • London (UK),
  • Zurich (CH).
你可以选择其中任意一个服务器连接 OpenVPN。
2、你可以添加被墙的网站
登录之后,你可以输入任意网站的链接并把它们添加到 Private Tunnel 页面,方便直接打开。
3、你可以用于 Windows 和 Mac
Private Tunnel 支持 Windows XP、Vista、Windows 7 以及 Mac OSX。

二、Private Tunnel 的不足之处

Private Tunnel 有以下两个不足的地方:
1、它只提供 100 MB 的免费流量
虽然你每邀请一个朋友购买 Private Tunnel 就可以获得 10 GB 的流量,但是这并不是一件容易的事。
2、美国的服务器被墙
我在测试的时候,发现 Private Tunnel 的美国服务器已经被墙,无法直接连接,但是可以先启用其他 VPN,然后再连接,连接上之后,再停用之前的那个 VPN,不过这种方法有点蛋疼。

三、如何使用 Private Tunnel?

要使用 Private Tunnel 提供的免费 OpenVPN 服务,你只需要进行以下三个操作:
1、注册一个帐号
Sign up Private Tunnel
只要输入你的邮箱地址和任意密码,就可以创建一个 Private Tunnel 免费帐号了。
2、下载并安装 OpenVPN Connect 软件
Download OpenVPN Connect
帐号创建之后,你会收到一封验证邮件,点击邮件里面的链接,你就可以直接登录 Private Tunnel 网站,选择前面提到的那三个服务器中的任意一个,并点击 "Connect" 按钮,然后就可以下载并安装一个叫 OpenVPN Connect 的软件。
安装完成之后,你就可以通过 Private Tunnel 翻墙了。
3、切换服务器
Change another Private Tunnel Server
如果当前连接的服务器很慢或者掉线甚至连接不上,你可以在 Private Tunnel 网站上选择另外一个服务器,然后点击 "Connect" 按钮就可以了。
小技巧:
1. 除了邀请朋友去购买 Private Tunnel 服务之外,你也可以通过注册多个帐户去获得更多的免费 OpenVPN 流量。

2013年2月26日星期二

linux系統的設定檔: /etc/crontab


這個『 crontab -e 』是針對使用者的 cron 來設計的,如果是『系統的例行性任務』時, 該怎麼辦呢?是否還是需要以 crontab -e 來管理你的例行性工作排程呢?當然不需要,你只要編輯 /etc/crontab這個檔案就可以啦!有一點需要特別注意喔!那就是 crontab -e 這個 crontab 其實是 /usr/bin/crontab 這個執行檔,但是 /etc/crontab 可是一個『純文字檔』喔!你可以 root 的身份編輯一下這個檔案哩!
基本上, cron 這個服務的最低偵測限制是『分鐘』,所以『 cron 會每分鐘去讀取一次 /etc/crontab 與 /var/spool/cron 裡面的資料內容 』,因此,只要你編輯完 /etc/crontab 這個檔案,並且將他儲存之後,那麼 cron 的設定就自動的會來執行了!
Tips:
在 Linux 底下的 crontab 會自動的幫我們每分鐘重新讀取一次 /etc/crontab 的例行工作事項,但是某些原因或者是其他的 Unix 系統中,由於 crontab 是讀到記憶體當中的,所以在你修改完 /etc/crontab 之後,可能並不會馬上執行, 這個時候請重新啟動 crond 這個服務吧!『/etc/init.d/crond restart』
鳥哥的圖示
廢話少說,我們就來看一下這個 /etc/crontab 的內容吧!
[root@www ~]# cat /etc/crontab
SHELL=/bin/bash                     <==使用哪種 shell 介面
PATH=/sbin:/bin:/usr/sbin:/usr/bin  <==執行檔搜尋路徑
MAILTO=root                         <==若有額外STDOUT,以 email將資料送給誰
HOME=/                              <==預設此 shell 的家目錄所在

# run-parts
01  *  *  *  *   root      run-parts /etc/cron.hourly   <==每小時
02  4  *  *  *   root      run-parts /etc/cron.daily    <==每天
22  4  *  *  0   root      run-parts /etc/cron.weekly   <==每週日
42  4  1  *  *   root      run-parts /etc/cron.monthly  <==每個月 1 號
分 時 日 月 週 執行者身份  指令串
看到這個檔案的內容你大概就瞭解了吧!呵呵,沒錯!這個檔案與將剛剛我們下達 crontab -e 的內容幾乎完全一模一樣!只是有幾個地方不太相同:
  • MAILTO=root

    這個項目是說,當 /etc/crontab 這個檔案中的例行性工作的指令發生錯誤時,或者是該工作的執行結果有 STDOUT/STDERR 時,會將錯誤訊息或者是螢幕顯示的訊息傳給誰?預設當然是由系統直接寄發一封 mail 給 root 啦!不過, 由於 root 並無法在用戶端中以 POP3 之類的軟體收信,因此,鳥哥通常都將這個 e-mail 改成自己的帳號,好讓我隨時瞭解系統的狀況!例如: MAILTO=dmtsai@my.host.name
  • PATH=....

    還記得我們在第十一章的 BASH 當中一直提到的執行檔路徑問題吧! 沒錯啦!這裡就是輸入執行檔的搜尋路徑!使用預設的路徑設定就已經很足夠了!
  • 01 * * * * root run-parts /etc/cron.hourly

    這個 /etc/crontab 裡面預設定義出四項工作任務,分別是每小時、每天、每週及每個月分別進行一次的工作! 但是在五個欄位後面接的並不是指令,而是一個新的欄位,那就是『執行後面那串指令的身份』為何!這與使用者的 crontab -e 不相同。由於使用者自己的 crontab 並不需要指定身份,但 /etc/crontab 裡面當然要指定身份啦!以上表的內容來說,系統預設的例行性工作是以 root 的身份來進行的。

    那麼後面那串指令是什麼呢?你可以使用『 which run-parts 』搜尋看看,其實那是一個 bash script 啦!如果你直接進入 /usr/bin/run-parts 去看看, 會發現這支指令會將後面接的『目錄』內的所有檔案捉出來執行!這也就是說『 如果你想讓系統每小時主動幫你執行某個指令,將該指令寫成 script,並將該檔案放置到 /etc/cron.hourly/ 目錄下即可』的意思!

    現在你知道系統是如何進行他預設的一堆例行性工作排程了嗎?如果你下達『 ll /etc/cron.daily 』就可以看到一堆檔案, 那些檔案就是系統提供的 script ,而這堆 scripts 將會在每天的凌晨 4:02 開始運作!這也是為啥如果你是夜貓族, 就會發現奇怪的是,Linux 系統為何早上 4:02 開始會很忙碌的發出一些硬碟跑動的聲音!因為他必須要進行 makewhatis, updatedb, rpm rebuild 等等的任務嘛!
由於 CentOS 提供的 run-parts 這個 script 的輔助,因此 /etc/crontab 這個檔案裡面支援兩種下達指令的方式, 一種是直接下達指令,一種則是以目錄來規劃,例如:
  • 指令型態
    01 * * * * dmtsai mail -s "testing" kiki < /home/dmtsai/test.txt
    以 dmtsai 這個使用者的身份,在每小時執行一次 mail 指令。
  • 目錄規劃
    */5 * * * * root run-parts /root/runcron
    建立一個 /root/runcron 的目錄,將要每隔五分鐘執行的『可執行檔』都寫到該目錄下, 就可以讓系統每五分鐘執行一次該目錄下的所有可執行檔。
好!你現在大概瞭解了這一個咚咚吧!OK!假設你現在要作一個目錄,讓系統可以每 2 分鐘去執行這個目錄下的所有可以執行的檔案,你可以寫下如下的這一行在 /etc/crontab 中:
*/2 * * * * root run-parts /etc/cron.min
當然囉, /etc/cron.min 這個目錄是需要存在的喔!那如果我需要執行的是一個『程式』而已, 不需要用到一個目錄呢?該如何是好?例如在偵測網路流量時,我們希望每五分鐘偵測分析一次, 可以這樣寫:
*/5 * * * * root /bin/mrtg /etc/mrtg/mrtg.cfg
如何!建立例行性命令很簡單吧!如果你是系統管理員而且你的工作又是系統維護方面的例行任務時, 直接修改 /etc/crontab 這個檔案即可喔!又便利,又方便管理呢!

小標題的圖示一些注意事項
有的時候,我們以系統的 cron 來進行例行性工作的建立時,要注意一些使用方面的特性。 舉例來說,如果我們有四個工作都是五分鐘要進行一次的,那麼是否這四個動作全部都在同一個時間點進行? 如果同時進行,該四個動作又很耗系統資源,如此一來,每五分鐘不是會讓系統忙得要死? 呵呵!此時好好的分配一些執行時間就 OK 啦!所以,注意一下:

媒体盘点全球黑帮:俄黑帮贩卖核材料成美国梦魇



2013-02-26 07:46:00 来源: 人民网(北京) 
2013年1月,“俄罗斯黑帮之王”阿斯兰·乌索扬遭暗杀,黑帮高层在1月26日举行秘密会议,协商“战略”布局,谋求扩张势力,规划由“塔里耶尔·奥尼亚尼帮派”控制的有组织犯罪团伙的战略,协商“后乌索扬”时代行动。

苏联1991年解体后,俄罗斯社会持续动荡。犯罪集团通常以暗杀等手段控制利润丰厚的产业,扩张地盘。这期间,奥尼亚尼逐步建立自己的犯罪集团,涉及毒品、赌博、武器销售和自然资源等领域,地盘覆盖原苏联地区。

纵观俄、美、日、意等全球著名黑帮,虽然行事方式或野蛮或冠冕堂皇,但他们借势力扩张对地区乃至世界政治经济产生的影响都是相同的。

俄罗斯黑帮的核交易

在俄罗斯叶卡捷琳堡的一个墓园,矗立着一些用进口大理石制作的墓碑。墓碑上雕刻着主人生前的形象,他们有的穿着皮夹克,手里拿着汽车钥匙,有的裸露身体展示文身,有的抽着雪茄接打电话。他们,就是俄罗斯的黑帮,有些已经入土为安,但多数还横行于世。

2012年12月9日,在俄罗斯卡巴尔达-巴尔卡尔共和国首府纳利奇克,一名电视新闻主持被疑似黑帮成员的杀手连射三枪身亡,而死者的两位主播同事也曾接到死亡威胁。调查部门估计,黑帮意在迫使当地传媒停止报道当局打击黑帮的行动。

这样的事情屡见不鲜,2012年3月20日,俄罗斯银行家格尔曼·戈尔本佐夫在伦敦遇刺;2006年9月,俄罗斯央行副行长科兹洛夫就因为领导反洗钱运动遭枪杀。

与意大利黑帮不同,俄罗斯不需要贿赂政府官员,因为黑社会的头面人物早已坐在政府的机要部门,他们甚至控制和影响着几个重要的行业。贪官和黑帮分子互相勾结,协助黑帮进行内幕交易、避税甚至杀死竞争对手。2012年美国的官方报告称,2/3的俄罗斯经济被犯罪组织掌控,其中包括40%的私营经济和60%的国有企业,全俄1740家银行中的大约一半也被黑帮所控制。

近年来,俄罗斯黑帮更加熟悉国际业务,世界上的其他黑帮也成了他们重要的生意伙伴。他们向尼日利亚提供武器,从哥伦比亚购买毒品,与意大利黑手党合作洗钱,跟日本山口组携手开拓色情市场。

对长期从事军火交易的俄罗斯黑帮来说,贩卖核材料也是轻车熟路。而这也是美国政府一直以来挥之不去的梦魇。美国联邦调查局局长认为,俄罗斯黑帮已经取代了前苏联军队,成为欧美安全体系的新威胁。

美国国防部曾表示,根据情报可以推断,“基地”组织已经对俄罗斯黑市上的核武器及大规模杀伤性武器进行了考察,可能已和俄罗斯黑帮取得了联系。

“体面”的日本山口组

在很多人眼里,黑帮都是身上背着刀疤和文身,无恶不作的暴利团伙。但在今天的日本,黑帮的“进化”程度之高足以颠覆绝大多数人的观念。

笔挺的西装,斯文的领带,印有照片的胸卡和名片,黑框眼镜和公文包是当今日本多数黑帮成员的日常装扮。如果不细看他们袖口或脖子上暴露出的文身和可能存在的断指,很多人会把他们当成公务员或工薪族。

发达国家中,日本是唯一公开允许有组织的黑社会团体存在的国家。目前,日本全国有22个团体被定为性质恶劣的“指定暴力团”,这22个团体鼎盛时期成员超过20万人。

在这22个团体中,人数最多、势力最大的是山口组。根据日本警察厅日前公布的报告,到2011年年底,山口组人数略有下降,但仍有成员7.3万人。

冠冕堂皇的背后,避免不了黑帮的犯罪本质。

根据2012年2月,美国财务部指出,山口组的犯罪活动包括在日本及其他国家贩毒、偷运军火、贩卖人口、卖淫和洗黑钱等,每年的收益预计达到数十亿美元。该组织已渗透至美国金融及商业体系,干扰了美国金融市场的运作秩序。

有人估计,包括山口组在内的日本黑帮年收入在1000亿美元以上,其中35%来自毒品,45%来自洗钱和其他犯罪所得,其余20%是正当投资所得的合法收入。

山口组偶尔也干点“正事”。

在山口组总部门口有一个醒目的标志牌,上面清晰地写着:我们不允许使用童工,不卖毒品,也不乱扔烟头。山口组内部还设有“奖学金”制度,成绩优秀的成员可以被派到欧美国家留学。山口组成员还会维持自己地盘上的社会秩序,有时甚至会先于警方调查“破案”,并将罪犯交予警察绳之以法。

近年来,日本黑帮的形象越来越好,在当地居民心目中堪比政府。令日本民众印象最深的或许是山口组在两次大地震后的表现。

2011年日本福岛地震后,日本政府反应缓慢,山口组成员却在第一时间将食物、水、毯子、盥洗用品等救援物资用卡车从东京和神户运送到日本东北部灾区的大小避难所中。山口组共向灾区运送了超过70车救援物资,总价值超过50万美元。他们行动迅速,悄无声息。

早在1995年阪神发生大地震后,山口组就曾积极地参与民间救援任务。

纵横世界的意大利黑手党

2012年在11日,在美国公开的数千份罗伯特·F·肯尼迪的文件中,一份中央情报局的文件记录了一项与黑手党有关的刺杀古巴革命领导人卡斯特罗的计划。这项计划中,黑手党成员和“爱国的古巴流亡者”同意收10万美元的报酬来暗杀卡斯特罗,另外还要2500美元作为经费。

以残忍著称的黑手党已经存在了近800年,然而诞生初期的黑手党却和现在的黑手党大不相同。

1282年3月30日复活节前一天,意大利西西里首府巴勒莫的一个少女在结婚当天被法国士兵强奸,西西里民众开始了疯狂的报复,他们高喊“Morto Alla Francia,Italia Anela”(“消灭法国是意大利的渴求”),后来,这句话的缩写Mafia就成了黑手党的名称,一个贫苦农民为求生存而联合起来的秘密帮会组织也从此产生。

然而,时过境迁,黑手党如今却演化成为一个十恶不赦的恐怖组织,随着意大利人的外迁,黑手党的势力遍布全球,并在国际社会扮演角色。目前,美国和加拿大都已经成为黑手党洗钱犯罪的温床。

如今,意大利很多地方都有被黑手党控制的可能。比如,在意大利南部雷焦卡拉布里亚市,不少官员与意大利四大黑手党之一“光荣会”有牵连,为此,意大利中央政府2012年10月9日不得不宣布,解雇包括市长在内的30名雷焦卡拉布里亚市政府及议会成员。

2012年7月24日,意大利西西里多名检察官正寻求对该国一批前政要发起审判,这些包括意大利前政府部长、国会议员和司法人员的政要被指控在上世纪90年代初与黑手党进行幕后交易。此前,意大利一些落网黑手党成员供称,前总理贝卢斯科尼早年也曾向黑手党上供寻求保护。

猖狂的哥伦比亚贩毒黑帮

世界上或许没有一个黑帮能像哥伦比亚黑帮那样肆无忌惮,劫掠军机,悬赏杀死警察。

2012年年初哥伦比亚的大街上,黑帮四处散发传单,传单上写着,凡杀一名警察,可获巫拉贝诺帮提供的500美元赏金,如果杀害一名扫毒特警赏金更高。

巫拉贝诺帮是哥伦比亚北部从事贩毒活动的主要黑帮,2012年元旦之后,巫拉贝诺帮成员在北部各地架设路障,严格控管物流,并警告当地商家不得营业,使得当地许多社区几乎陷入瘫痪。

哥伦比亚是目前世界上最大的可卡因加工国和贩运国,是美国可卡因的最大输出国和大麻最大的供货基地之一。由于贩卖毒品,这里的黑帮财大气粗,哥伦比亚第二大城市麦德林几乎成了毒枭们的地盘,每天都有几个人死在那里,麦德林被人们称为“杀人城”。

曾被《财富》杂志评选为全球七大富豪之一的巴勃罗·埃斯科巴就是在麦德林“发家致富”的。埃斯科巴手下有4万人组成的私人军队,他们装备精良。此前,埃斯科巴看上了哥伦比亚海军的一架号称“空中坦克”的战机后,他便命令出动3架战斗机把“空中坦克”迫降在自己的机场,将其变为自己的私人专机,并命名为“云雀”。?

在哥伦比亚甚至整个美洲,埃斯科巴从来都没有把谁放在眼里。逮捕他的警察,不出3天就被人射杀;审判他的法官,妻子被轮奸后,内衣被寄到法官办公室;通缉他的哥伦比亚总检察长,被他反过来悬赏1亿美元捉拿,最后横尸街头。1987年,他的兄弟奥乔亚被捕,负责审判的哥伦比亚最高法院院长先后辞职,司法部长不得不取消逮捕令。

由于长期向美国境内输送毒品,美国政府一直想和哥伦比亚政府联手除掉埃斯科巴,但谈何容易。


1984年3月,在美国军事顾问的指挥下,5000名哥政府军乘坐大力神运输机直捣麦德林集团的老巢,但遭到埃斯科巴的反击,一个月后,哥伦比亚禁毒总指挥——司法部长拉腊被枪杀。两个月后,50多名毒贩干脆冲入了哥伦比亚司法部大厦,试图绑架正在开会的司法部、最高法院、最高检察院和缉毒警察局的高级官员。

1991年,哥伦比亚政府接受了埃斯科巴提出的3项招安条件:保证他的个人财产合法化;惩办侵犯过毒贩及其家属人权的警察;建一座由正规部队看守的专门监狱以确保他们的生命安全。1993年12月2日,埃斯科巴终于被军方击毙。

虽然埃斯科巴死了,但哥伦比亚的黑帮一直在疯狂生长。现在,很多黑帮和警方、政府的利益联系更加紧密。

c#加密/解密:一个可逆加密的类(使用3DES加密)

    3DES加密:表示三重数据加密标准算法的基类,TripleDES 的所有实现都必须从此基类派生。是从 SymmetricAlgorithm 类里继承出来。一、提要 命名空间:System.Security.Cryptography.TripleDES 类 简单说明: 表示三重数
3DES加密:表示三重数据加密标准算法的基类,TripleDES 的所有实现都必须从此基类派生。是从 SymmetricAlgorithm 类里继承出来。
一、提要
命名空间:System.Security.Cryptography.TripleDES 类
简单说明: 表示三重数据加密标准算法的基类,TripleDES 的所有实现都必须从此基类派生。是从 SymmetricAlgorithm 类里继承出来。TripleDES 使用 DES 算法的三次连续迭代。它可以使用两个或三个 56 位密钥。
使用目的:比较安全的加密一种方式,密钥和矢量的不同,会生产不同的加密字串。因为是DES算法的三次连续迭代,而且算法可逆,这样对于数据保密性和可恢复性都不错。
二、代码示例
本代码参照了部分MSDN上的代码示例,再根据自己的实际情况,补充了一部分MSDN上没有提到的内容

using System;
using System.Security;
using System.Security.Cryptography;
using System.IO;
using System.Text;
using System.Threading;
namespace TRIP3DES
{
/// <summary>
/// Class1 的摘要说明。
/// </summary>
public class dllEncrypt
{
//密钥
private const string sKey = "qJzGEh6hESZDVJeCnFPGuxzaiB7NLQM3";
//矢量,矢量可以为空
private const string sIV = "qcDY6X+aPLw=";
//构造一个对称算法
private SymmetricAlgorithm mCSP = new TripleDESCryptoServiceProvider();
public dllEncrypt(){}
#region public string EncryptString(string Value)
/// <summary>
/// 加密字符串
/// </summary>
/// <param name="Value">输入的字符串</param>
/// <returns>加密后的字符串</returns>
public string EncryptString(string Value)
{
ICryptoTransform ct;
MemoryStream ms;
CryptoStream cs;
byte[] byt;
mCSP.Key = Convert.FromBase64String(sKey);
mCSP.IV = Convert.FromBase64String(sIV);
//指定加密的运算模式
mCSP.Mode = System.Security.Cryptography.CipherMode.ECB;
//获取或设置加密算法的填充模式
mCSP.Padding = System.Security.Cryptography.PaddingMode.PKCS7;
ct = mCSP.CreateEncryptor(mCSP.Key, mCSP.IV);
byt = Encoding.UTF8.GetBytes(Value);
ms = new MemoryStream();
cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
cs.Write(byt, 0, byt.Length);
cs.FlushFinalBlock();
cs.Close();
return Convert.ToBase64String(ms.ToArray());
}
#endregion
#region public string DecryptString(string Value)
/// <summary>
/// 解密字符串
/// </summary>
/// <param name="Value">加过密的字符串</param>
/// <returns>解密后的字符串</returns>
public string DecryptString(string Value)
{
ICryptoTransform ct;
MemoryStream ms;
CryptoStream cs;
byte[] byt;
mCSP.Key = Convert.FromBase64String(sKey);
mCSP.IV = Convert.FromBase64String(sIV);
mCSP.Mode = System.Security.Cryptography.CipherMode.ECB;
mCSP.Padding = System.Security.Cryptography.PaddingMode.PKCS7;
ct = mCSP.CreateDecryptor(mCSP.Key, mCSP.IV);
byt = Convert.FromBase64String(Value);
ms = new MemoryStream();
cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
cs.Write(byt, 0, byt.Length);
cs.FlushFinalBlock();
cs.Close();
return Encoding.UTF8.GetString(ms.ToArray());
}
#endregion
}
}
三、总结
做成类库对于密钥和矢量的保管比较方便,输入输出全部是string型变量,这样也比较方便,密钥的生成可以用mSCP. GenerateKey()来生成,矢量的生成也可以用mCSP.GenerateIV()来生成。大家也可以自己灵活的编写符合自己的3DES算法。

c#中利用Process调用外部ftp.exe


实际需求:利用process调用ftp.exe,程序在“int bytesReadPassword = stdoutStream.Read(bufferPassword, 0, bufferPassword.Length);”处出现阻塞
以下代码为正常流程,异常情况暂时未考虑。
C# code
   ftp = new Process();
            ftp.StartInfo.FileName = "ftp.exe";
            ftp.StartInfo.Arguments = host; //remote host IP Address.
            ftp.StartInfo.UseShellExecute = false;
            ftp.StartInfo.RedirectStandardOutput = true;
            ftp.StartInfo.RedirectStandardInput = true;
            ftp.StartInfo.RedirectStandardError = true;
            ftp.StartInfo.CreateNoWindow = false;
            ftp.Start();
            stdoutStream = ftp.StandardOutput.BaseStream;
            stdinpStream = ftp.StandardInput.BaseStream;          
           
            //取得进程启动后的output,应该为提示用户输入登录用户名
            byte[] buffer = new byte[1024];
            int bytesRead = stdoutStream.Read(buffer, 0, buffer.Length);
            if (bytesRead <= 0)
            {
                throw new Exception("Host does not respond as expected before timeout");
            }
            string str = Encoding.ASCII.GetString(buffer, 0, bytesRead);
            //输入登录用户名
            if (str.Contains("User"))
            {
                if (stdinpStream.CanWrite)
                {
                    string user = String.Format("{0}", username);
                    Byte[] cmd = Encoding.ASCII.GetBytes((user + "
").ToCharArray());
                    stdinpStream.Write(cmd, 0, cmd.Length);
                    stdinpStream.Flush();
                }
            }                    
            //取得输入用户名后的output,应该为提示用户输入登录密码
            byte[] bufferRoot = new byte[1024];
            int bytesReadRoot = stdoutStream.Read(bufferRoot, 0, bufferRoot.Length);
            if (bytesReadRoot <= 0)
            {
                throw new Exception("Login failed.");
            }
            string strRoot = Encoding.ASCII.GetString(bufferRoot, 0, bytesReadRoot);
            //输入登录密码
            if (strRoot.Contains("Password"))
            {
                if (stdinpStream.CanWrite)
                {
                    string userpassword = String.Format("{0}", password);
                    Byte[] cmd1 = Encoding.ASCII.GetBytes((userpassword + "
").ToCharArray());
                    stdinpStream.Write(cmd1, 0, cmd1.Length);
                    stdinpStream.Flush();
                }
            }
            //取得登录成功后的信息
            byte[] bufferPassword = new byte[1024];
            int bytesReadPassword = stdoutStream.Read(bufferPassword, 0, bufferPassword.Length);
            if (bytesReadPassword <= 0)
            {
                throw new Exception("Login failed.");
            }
            string strPassword = Encoding.ASCII.GetString(bufferPassword, 0, bytesReadPassword);



注明:远程机器上的ftp服务没有问题,手工能登录成功。

如果把ftp.exe换成其他的程序,没有问题。

2013年2月25日星期一

C#中实现文本框的滚动条自动滚到最底端



      1、配置textBox的Multiline属性为true;
2、配置textBox的ScrollBars属性为Vertical,实现纵向滚动条;
3、然后如下语句实现自己滚动:

       private void textBox3_TextChanged_1(object sender, EventArgs e)
        {
            textBox3.SelectionStart = textBox3.Text.Length;
            textBox3.ScrollToCaret();
        }

Launching a process and displaying its standard output



Sample Image - LaunchProcess.png

Introduction

I wanted to launch a script from a Windows Form application and display the standard output in a text box as the process was running.  Surely you're not surprised to learn that multithreading is involved.  It turns out you'll have at least four threads running to do this simple task.  To keep things simple and sane, I've reused code from other another source, so I must first give credit to the MSDN article "Give Your .NET-based Application a Fast and Responsive UI with Multiple Threads"  by I.D. Griffiths.  I highly suggest reading this article for more background on multithreading in Windows Forms applications.  Thanks also to Chad Christensen for his suggestions in using a RichTextBox.

Creating a class to call a process

A script or executable can be run using System.Diagnostics.Process.  The string FileName is set to the executable (e.g. perl.exe, Run.bat, ConsoleApplication.exe).  The string Arguments is set to the command-line arguments for that executable (e.g. perlscript.pl, filename1.txt filename2.txt, etc).  The following code will start that executable.
    Process process = new Process();
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.RedirectStandardOutput = true;
    process.StartInfo.RedirectStandardError = true;
    process.StartInfo.CreateNoWindow = true;
    process.StartInfo.FileName = FileName;
    process.StartInfo.Arguments = Arguments;
    process.StartInfo.WorkingDirectory = WorkingDirectory;
    process.Start();
Notice that the standard output and standard error have both been redirected.  There are two StreamReaders in the Process class that can be used to read the output: Process.StandardOutput andProcess.StandardError.  Often, the output is not read until after the process has finished, as in the following:
    string output = process.StandardOutput.ReadToEnd();
Reading to the end will not work for this application, since we want to read the data as the process is running.

Multiple threads

The solution is to use multiple threads.  One thread is dedicated to running the process and two more threads are dedicated to reading the standard error and standard output.  This is mentioned in MSDNdocumentation.  Each of these two threads will run a simple function that sits in a loop reading from the stream until the stream is closed.
    void ReadStdOut()
    {
        string str;
        while ((str = process.StandardOutput.ReadLine()) != null)
        {
            // do something with str
        }
    }
After each line is read into str, we would like to notify a windows form to display the text.  Raising an event is probably the best way to accomplish this.  For every new line of text received (on either StandardOutput or StandardError) an event will be raised.  A windows form class can subscribe to these events and update a text box.  Simple, but it won't quite work without some additional work.

Important rule of windows forms

There is an important rule of windows forms and multithreading.  Controls are (almost entirely) not thread safe.  This means that an event raised from any thread other than the UI Thread cannot use methods or properties of a control.  There are a few methods guaranteed to be safe including Control.Invoke and Control.BeginInvoke.  These methods are used to run a function on the UI thread.
Thankfully, we can inherit from the class AsyncOperation (written by I.D. Griffiths from the above mentioned MSDN article) to solve several problems.  First, this class allows us to raise an event on a UI thread of a hosting or target control.  The above function becomes:
    public delegate void DataReceivedHandler(object sender,
        DataReceivedEventArgs e);

    public event DataReceivedHandler StdOutReceived;

    void ReadStdOut()
    {
        string str;
        while ((str = process.StandardOutput.ReadLine()) != null)
        {
            FireAsync(StdOutReceived, this, new DataReceivedEventArgs(str));
        }
    }
FireAsync is a method provided by the class AsyncOperation.  It raises an event (or more specifically invokes any delegate) on the UI thread of a form or control.  StdOutReceived is the event that will be raised.  DataReceivedEventArgs is a class derived from EventArgs that has a single string containing the text to be displayed (its definition is not shown here for brevity).
The second thing AsyncOperation provides is a method of canceling a process.  Let's take a look at that class in more detail.

Inheriting from AsyncOperation

AsyncOperation is an abstract base class that assists in creating cancelable worker threads that can fire events back on a UI control (or form).  It provides two main methods that are called by a form class: Start() andCancel().
AsyncOperation requires that one method be overridden: DoWork(). This method is called when the Start() method is called.  As the method runs, it is expected to watch for a flag CancelRequested that is set from a call to Cancel().  If the flag is true, the method should acknowledge the cancel and return.
The implementation of DoWork() is as follows:
    void protected override void DoWork()()
    {
        // Start a new process for the cmd
        Process process = new Process();
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.CreateNoWindow = true;
        process.StartInfo.FileName = FileName;
        process.StartInfo.Arguments = Arguments;
        process.StartInfo.WorkingDirectory = WorkingDirectory;
        process.Start();

        
        // Invoke stdOut and stdErr readers - each
        // has its own thread to guarantee that they aren't
        // blocked by, or cause a block to, the actual
        // process running (or the gui).
        new MethodInvoker(ReadStdOut).BeginInvoke(null, null);
        new MethodInvoker(ReadStdErr).BeginInvoke(null, null);

        // Wait for the process to end, or cancel it
        while (! process.HasExited)
        {
            Thread.Sleep(SleepTime); // sleep
            if (CancelRequested)
            {
                // Not a very nice way to end a process,
                // but effective.
                process.Kill();
                AcknowledgeCancel();
            }
        }

    }
The methods DoWork()ReadStdOut(), and ReadStdErr(), the properties FileName and Arguments, and the events StdOutReceived and StdErrReceived are all added to a class ProcessCaller which derives from AsyncOperation.  Both classes can be downloaded as part of the zipfile at the top of the page.

The form

As shown in the picture above, the form is quite simple.  It consists of a rich text box to show the standard output and standard input, a button to run a process (Ok), and a button to cancel the process (Cancel).
The Ok button calls the Start() method on ProcessCaller and the Cancel button calls the Cancel() method.  The events StdOutRecieved and StdErrReceived are handled by the following function:
    private void writeStreamInfo(object sender, DataReceivedEventArgs e)
    {
        this.richTextBox1.AppendText(e.Text + Environment.NewLine);
    }

Improvements

Adding a progress bar to the form is one nice improvement for the user interface.  Of course, you have to know the progress of the program being run.  One option is to have the script tell you explicitly in the standard output with lines such as: "Percent completion = 30".  Your "writeStreamInfo" function would filter those lines and update a progress bar.
Standard Error can be displayed in red or some other color (or in a separate rich text box) to highlight any errors found.  At the end of the process, a dialog could be displayed with a list of all errors.
Providing support for standard input shouldn't be too difficult, but integrating it with the windows form may be tough.  Perhaps a separate single-line text box whose contents are sent to the standard input stream through a method on ProcessCaller.
These are just a few ideas of improvements you can make.

Conclusion

Using the class AsyncOperation reduced the design complexity of this program.  Hopefully, the class ProcessCaller will provide you just as much help in reducing the complexity of running scripts and monitoring the output.

Revision History

  • 2003-Jul-31 : Original Post
  • 2003-Aug-05 : Fixed some spelling / grammatical mistakes (oops)
 

Launching a process and displaying its standard output



Sample Image - LaunchProcess.png

Introduction

I wanted to launch a script from a Windows Form application and display the standard output in a text box as the process was running.  Surely you're not surprised to learn that multithreading is involved.  It turns out you'll have at least four threads running to do this simple task.  To keep things simple and sane, I've reused code from other another source, so I must first give credit to the MSDN article "Give Your .NET-based Application a Fast and Responsive UI with Multiple Threads"  by I.D. Griffiths.  I highly suggest reading this article for more background on multithreading in Windows Forms applications.  Thanks also to Chad Christensen for his suggestions in using a RichTextBox.

Creating a class to call a process

A script or executable can be run using System.Diagnostics.Process.  The string FileName is set to the executable (e.g. perl.exe, Run.bat, ConsoleApplication.exe).  The string Arguments is set to the command-line arguments for that executable (e.g. perlscript.pl, filename1.txt filename2.txt, etc).  The following code will start that executable.
    Process process = new Process();
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.RedirectStandardOutput = true;
    process.StartInfo.RedirectStandardError = true;
    process.StartInfo.CreateNoWindow = true;
    process.StartInfo.FileName = FileName;
    process.StartInfo.Arguments = Arguments;
    process.StartInfo.WorkingDirectory = WorkingDirectory;
    process.Start();
Notice that the standard output and standard error have both been redirected.  There are two StreamReaders in the Process class that can be used to read the output: Process.StandardOutput andProcess.StandardError.  Often, the output is not read until after the process has finished, as in the following:
    string output = process.StandardOutput.ReadToEnd();
Reading to the end will not work for this application, since we want to read the data as the process is running.

Multiple threads

The solution is to use multiple threads.  One thread is dedicated to running the process and two more threads are dedicated to reading the standard error and standard output.  This is mentioned in MSDNdocumentation.  Each of these two threads will run a simple function that sits in a loop reading from the stream until the stream is closed.
    void ReadStdOut()
    {
        string str;
        while ((str = process.StandardOutput.ReadLine()) != null)
        {
            // do something with str
        }
    }
After each line is read into str, we would like to notify a windows form to display the text.  Raising an event is probably the best way to accomplish this.  For every new line of text received (on either StandardOutput or StandardError) an event will be raised.  A windows form class can subscribe to these events and update a text box.  Simple, but it won't quite work without some additional work.

Important rule of windows forms

There is an important rule of windows forms and multithreading.  Controls are (almost entirely) not thread safe.  This means that an event raised from any thread other than the UI Thread cannot use methods or properties of a control.  There are a few methods guaranteed to be safe including Control.Invoke and Control.BeginInvoke.  These methods are used to run a function on the UI thread.
Thankfully, we can inherit from the class AsyncOperation (written by I.D. Griffiths from the above mentioned MSDN article) to solve several problems.  First, this class allows us to raise an event on a UI thread of a hosting or target control.  The above function becomes:
    public delegate void DataReceivedHandler(object sender,
        DataReceivedEventArgs e);

    public event DataReceivedHandler StdOutReceived;

    void ReadStdOut()
    {
        string str;
        while ((str = process.StandardOutput.ReadLine()) != null)
        {
            FireAsync(StdOutReceived, this, new DataReceivedEventArgs(str));
        }
    }
FireAsync is a method provided by the class AsyncOperation.  It raises an event (or more specifically invokes any delegate) on the UI thread of a form or control.  StdOutReceived is the event that will be raised.  DataReceivedEventArgs is a class derived from EventArgs that has a single string containing the text to be displayed (its definition is not shown here for brevity).
The second thing AsyncOperation provides is a method of canceling a process.  Let's take a look at that class in more detail.

Inheriting from AsyncOperation

AsyncOperation is an abstract base class that assists in creating cancelable worker threads that can fire events back on a UI control (or form).  It provides two main methods that are called by a form class: Start() andCancel().
AsyncOperation requires that one method be overridden: DoWork(). This method is called when the Start() method is called.  As the method runs, it is expected to watch for a flag CancelRequested that is set from a call to Cancel().  If the flag is true, the method should acknowledge the cancel and return.
The implementation of DoWork() is as follows:
    void protected override void DoWork()()
    {
        // Start a new process for the cmd
        Process process = new Process();
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.CreateNoWindow = true;
        process.StartInfo.FileName = FileName;
        process.StartInfo.Arguments = Arguments;
        process.StartInfo.WorkingDirectory = WorkingDirectory;
        process.Start();

        
        // Invoke stdOut and stdErr readers - each
        // has its own thread to guarantee that they aren't
        // blocked by, or cause a block to, the actual
        // process running (or the gui).
        new MethodInvoker(ReadStdOut).BeginInvoke(null, null);
        new MethodInvoker(ReadStdErr).BeginInvoke(null, null);

        // Wait for the process to end, or cancel it
        while (! process.HasExited)
        {
            Thread.Sleep(SleepTime); // sleep
            if (CancelRequested)
            {
                // Not a very nice way to end a process,
                // but effective.
                process.Kill();
                AcknowledgeCancel();
            }
        }

    }
The methods DoWork()ReadStdOut(), and ReadStdErr(), the properties FileName and Arguments, and the events StdOutReceived and StdErrReceived are all added to a class ProcessCaller which derives from AsyncOperation.  Both classes can be downloaded as part of the zipfile at the top of the page.

The form

As shown in the picture above, the form is quite simple.  It consists of a rich text box to show the standard output and standard input, a button to run a process (Ok), and a button to cancel the process (Cancel).
The Ok button calls the Start() method on ProcessCaller and the Cancel button calls the Cancel() method.  The events StdOutRecieved and StdErrReceived are handled by the following function:
    private void writeStreamInfo(object sender, DataReceivedEventArgs e)
    {
        this.richTextBox1.AppendText(e.Text + Environment.NewLine);
    }

Improvements

Adding a progress bar to the form is one nice improvement for the user interface.  Of course, you have to know the progress of the program being run.  One option is to have the script tell you explicitly in the standard output with lines such as: "Percent completion = 30".  Your "writeStreamInfo" function would filter those lines and update a progress bar.
Standard Error can be displayed in red or some other color (or in a separate rich text box) to highlight any errors found.  At the end of the process, a dialog could be displayed with a list of all errors.
Providing support for standard input shouldn't be too difficult, but integrating it with the windows form may be tough.  Perhaps a separate single-line text box whose contents are sent to the standard input stream through a method on ProcessCaller.
These are just a few ideas of improvements you can make.

Conclusion

Using the class AsyncOperation reduced the design complexity of this program.  Hopefully, the class ProcessCaller will provide you just as much help in reducing the complexity of running scripts and monitoring the output.

Revision History

  • 2003-Jul-31 : Original Post
  • 2003-Aug-05 : Fixed some spelling / grammatical mistakes (oops)