<?xml version="1.0" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="css/rss.xslt"?>
<?xml-stylesheet type="text/css" href="css/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>pencat's blog - 文档</title><link>http://blog.bigcomic.com/</link><description>我的日记 - </description><generator>RainbowSoft Studio Z-Blog 1.8 Devo Build 80201</generator><language>zh-CN</language><copyright>Copyright © 1998-2007 bigcomic.com All rights reserved.</copyright><pubDate>Sun, 05 Sep 2010 13:26:13 +0800</pubDate><item><title>南京修理工惊曝修车黑幕</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/292.html</link><pubDate>Tue, 13 Oct 2009 13:32:35 +0800</pubDate><guid>http://blog.bigcomic.com/post/292.html</guid><description><![CDATA[<p>&nbsp;<span class="Apple-style-span" style="font-family: 宋体; font-size: 14px; color: rgb(102, 102, 102); line-height: 21px; ">&nbsp; 据权威部门统计，截至2007年底，我国私家轿车保有量巳超过1800万辆，其中天津和广州每百户家庭拥有私家轿车分别为l7．4辆和12．7辆。<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp; 有车就得养车修车。然而，最近一项调查显示，对目前修车行业信不过的高达71．6％，基本信得过的只有11．4％。尽管有那么多人对修车行业的服务不满意，但他们一点办法也没有，因为他们根本就搞不清修车行业到底有多少黑幕&hellip;&hellip;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp; 一技在身，修车接触&ldquo;潜规则&rdquo;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp; 2008年3月18日，在南京市一家4s修车店当高级修理工的张宇清接到一个电话：他12岁的外甥女在跟同学一家驾车外出春游时出了车祸。张字清心里一紧，马上赶过去。外甥女虽然命保住了，但可能留下终身残疾。他一眼看出，事故车一定是在维修时被人做了手脚，不禁呆住了&hellip;&hellip;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp; 今年29岁的张宇清是南京市下关区人，10年前，他高中毕业后，到南京市一家民办小汽车修理学校学习。经过两年半学习，他取得了专业技术资格证书。结业后，他到南京几家机修厂做了几年的学徒工。由于他努力钻研，修车技术提高很快。两年后，只要仔细听听发动机的声音，他就能大概判断出汽车故障出在什么地方。然而，一些老师傅对张宇清说：&ldquo;搞汽修这一行，技术当然重要，但对其中的&lsquo;门道&rsquo;更不能不了解。&rdquo;张字清虚心地向他们请教什么是&ldquo;门道&rdquo;，师傅们说：&ldquo;这种事情只可意会，不可言传。时间长了，你自然就知道了。&rdquo;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp;&nbsp; 2005年夏，张宇清是比较成熟的机修工了。当时他在一家维修店当学徒，一天，一辆马自达6因电脑故障前来维修，师傅正好不在，张字清就上前帮车主检查。通过检查，张宇清发现汽车没有大毛病，只是电脑进水了，用电吹风吹干就行了。然而，正当他拿着电吹风准备吹的时候，老板把他叫到一边说：&ldquo;你这是干什么？都像你这样修车，大家喝西北风啊？想办法让他进行&lsquo;套餐维修&rsquo;，找个理由把电脑换掉!&rdquo;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp;&nbsp; 张宇清说：&ldquo;车子没什么毛病，这样做不是害人吗？&rdquo;老板压低嗓子盯着张宇清说道：&ldquo;玩得起好车的人都有钱，不宰他们宰谁？按我说的做！&rdquo;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp;&nbsp; 张宇清这才明白师傅们说的话，只好学着师傅们的样子对车主说，因为车子保养不当，很多零部件都到了更新期，最好按照&ldquo;套餐维修&rdquo;全面修理。当时车主还有点犹豫，老板走上前来，递给车主一支香烟说：&ldquo;车子可不是开玩笑的事情，你坐到驾驶位上就把身家性命交给了它，千万不能将就。你这车很多零部件如果不及时更新，路上随时都可能出问题。&rdquo;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp;&nbsp; 听了老板的话，车主才表态说：&ldquo;既然这样，那就&lsquo;套餐&rsquo;吧。&rdquo;结果，那辆车按套餐维修规定，把很多根本不需要更新的东西都更新了，光是更新那台电脑，车主就多花了4000元。这下子，本来20元就能解决的问题，车主花了7000多元。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp;&nbsp; 让张宇清有些气恼的是，事后，车主不光没觉得老板宰了他，反倒感激老板做事认真负责。张宇清心想，这些有钱人真是欠宰!不过，仅这次维修，他就拿了1000多元的提成。此后，他也学会了宰客，凡车主来修车，他总是找各种理由要求车主尽量多更换零部件。这样一来，他的&ldquo;业务量&rdquo;有了很大提高，收入自然也水涨船高。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp;&nbsp; 2006年初，通过考试，张宇清获得了民企小汽车维修三级技师职称，成了&ldquo;师傅&rdquo;级的高级技工，可以单独修车并带徒弟了。就在这时，张宇清谈了三年多的女朋友怀孕了。因为两人没有结婚，他好不容易才做通工作让她做了人流。但女朋友说：&ldquo;我都快30岁了，你们家到底什么时候才能买房给我们办喜事啊？&rdquo;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp;&nbsp; 本来，张宇清家的老宅子说是要拆迁的，父母准备到时候用安置房给他们结婚，但不知为什么，后来拆迁的事又没了消息，女朋友不愿意在破旧的老宅里结婚，张宇清每个月只有3000多元收入，家里也没有能力帮他买房，所以婚期一推再推。现在，听女朋友这么一说，他连忙哄女朋友说：&ldquo;亲爱的，你放心，今年年底前，我就是砸锅卖铁也买套房子跟你结婚!&rdquo; 话虽这么说，但当时张宇清手里根本没有多少钱，连付房子的首付款都拿不出，这事让他很头疼。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp; 疯狂宰客，花样百出月赚2万多</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp; 谁知，祸不单行。就在他不知如何兑现对女朋友的承诺时，母亲得了直肠癌，急需钱做手术。他的父母都是下岗工人，只有张宇清这一个儿子，他只得向师傅借了3万多元给母亲做手术。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp; 张宇清的师傅姓许，他劝张字清说：&ldquo;你也太死心眼了。像你这样下去，收入太少不说，时间长了，老板也会炒你的鱿鱼，因为你没帮老板赚到钱。不过，凭你现在的技术，只要你好好跟我学，收入一定会跟我一样多。&rdquo;张宇清说：&ldquo;我已经宰了不少车主啊!&rdquo;许师傅&ldquo;嗨&rdquo;了一声，说：&ldquo;那算什么？毛毛雨啦!有人还故意把发动机敲裂了宰车主呢!&rdquo;张宇清有点儿担心，说：&ldquo;万一被车主发现了怎么办？&rdquo;师傅说：&ldquo;那就得看你有没有绝招了。&rdquo;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp;&nbsp; 就在这时，有一辆大半新的本田雅阁来调整点火时间。许师傅向张宇清使了个眼色，那意思是&ldquo;看我的&rdquo;。调整点火是技术含量非常高的活儿，许师傅当着车主和张宇清的面仔细为汽车调整了点火时间，车主试了试．非常满意。许师傅说：&ldquo;我们这里专门修理汽车疑难杂症，以后有什么修不好的，别忘了来照顾我们的生意。找我就行，我姓许。&rdquo;说着，还递给车主一张名片。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp; 调整点火时间工时收费80元，张宇清觉得许师傅并没有宰车主。许师傅点燃一支香烟得意地说：&ldquo;别急，过几天你就知道了。&rdquo;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp;&nbsp; 果然，三天后，那位本田雅阁车主又来了。他径直找到许师傅说：&ldquo;不知为什么，上次调整了点火时间后，我的车还是没劲。跑了几家修理店都找不到原因，所以又找你来了。&rdquo;许师傅不紧不慢地问：&ldquo;是不是我点火时间没调好？&rdquo;车主忙说不是。于是许师傅开始仔细检查起汽车的发动机，然后说：&ldquo;你这车前期保养很不到位，发动机磨损严重，肯定无力。要想彻底治好毛病，最好是换发动机。&rdquo;当车主听说换发动机需要好几万元时，有些犹豫。许师傅说：&ldquo;这样吧，我帮你仔细修一下，但发动机缸头必须换，否则谁也没办法。&rdquo;换缸头也要花近两万元，车主还是答应了。汽车换了缸头，毛病果然好了。当然，许师傅也从这笔生意上拿了将近4000元的提成。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp;&nbsp; 可是，许师傅好像没做什么手脚啊!许师傅说：&ldquo;被你看出来，那还是我的绝招吗？想知道晚上就请我喝两杯。&rdquo;当天晚上，张宇清请许师傅喝酒。在酒桌上，张宇清终于搞明白了。原来，车主第一次来调整点火时间时，许师傅悄悄地在汽车发动机的空气格里塞了一小团棉纱，这样一来，发动机的通气渠道被堵住，汽车当然乏力。而这种秘密只有许师傅自己清楚，在别的地方根本检查不出来，所以车主很快成了他的回头客。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp;&nbsp;&nbsp; 许师傅说：&ldquo;那个换下来的缸头一点毛病也没有，以后把它换给别的车，我又能赚好几千。&rdquo;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp;&nbsp; 张宇清心想：修车的门道真的太深了，怪不得许师傅每个月都有两万多元的收入!于是他试着用自己知道的几种方法宰了几位车主，千方百计让车主多花钱，对方一点也不知情，甚至还大夸自己修车技术。这样，张宇清也第一次拿到了15000多元工资加提成。他对女朋友说：&ldquo;亲爱的，我现在完全有把握在年底以前挣到买房首付款。你就等着当我的新娘吧!&rdquo;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp;&nbsp; 开初，他没敢在那些关乎行车安全的事情上做手脚，只是玩一些让车主做冤大头、可以多赚点钱的&ldquo;猫腻&rdquo;。但几次做下来，他见什么问题也没出，胆子越来越大，不管车上的东西是否需要更换，他都千方百计劝车主换。如果车主犹豫，他就把后果说得很严重，大多数车主也就同意了。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp; 2007年的一天，在向一位车主推销新型刹车片时，车主坚决不愿意换，还说张宇清想宰他。张字清有些生气地想：真不识好歹了，自己并没有狠宰他，也戴上了宰客的帽子，看来不宰白不宰。他想起从许师傅那里学到的另一种宰客方法，于是往车子的刹车油里放了一些酒精。这样一来，用不了多久，汽车变速箱齿轮就会受损严重，由于酒精可以稀释刹车油，又能挥发，所以谁也发现不了。 果然，一周后，那辆车就出了问题。张宇清发现，自己在刹车油里加了酒精，刹车油失去了润滑作用，整个变速箱都被磨坏了，如果在高速路上高速行驶，很难说不出大问题。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp; 这都是自己做手脚造成的啊，万一出事故闹出人命，自己就是犯罪啊!他强压住狂跳的心，把磨损的部位指给车主看，说：&ldquo;都是你养车经验不足，又不听我们劝，还说我想宰你。这下可好，整个变速箱都得换了。&rdquo;结果车主再三认错，表示以后一定听张宇清的。那次，张字清一下子就拿了4000多元提成，车主还跟他建立一种&ldquo;信任&rdquo;的关系，从此完全掉入陷阱中。不过，从那以后，张宇清再也没敢往刹车油里加酒精了。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp;&nbsp; 2007年10月的一天，张宇清在偷换车主的零件时，不小心穿了帮，只得跳槽去一家4s店当师傅。在4s店，他又学会了新的宰客方法。 很多车主都认为4s店的技术力量好，配件质量也有保障，虽然收费较高，但玩车嘛，首先得放心。他们根本就不知道，其实在有些4s店修车，比在一些小店修车还不安全。在4s店工作的师傅。的确有一定技术，但正因为如此，如果他们做了手脚你也不会知道。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp;&nbsp; 张宇清很快就发现，4s店有个&ldquo;潜规则&rdquo;，就是当维修人员对病车的毛病判断不确定的时候，可以把别的车上的好零件装到&ldquo;病车&rdquo;上来证实自己的判断，经常事后根本就不把零件换回去，一是图省事，二是防止做二次手脚被发现。这样一来，可能一台只用了1年的功能完好的发动机，进厂维修或保养出来后，却变&ldquo;老&rdquo;了好几岁。2007年11月的一天，张宇清把一辆奥迪A6(图库 论坛)车的启动器拆下换到另一辆车上，后来被细心的车主发现了。车主当即跟店里发生争执，事后还向有关部门投诉了修车店。张宇清只说是自己忘了换回来，所以事情后来还是不了了之。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp;&nbsp; 张宇清最喜欢修理事故车。如果遇到事故车．他经常把所有的旧件甚至残次件都一口气换上去，把比较新的部件拿走。保险公司来人定损时，他就想办法跟定损人员搞好关系，甚至送些&ldquo;好处&rdquo;给对方，然后说这个不行了、那个也不行了，都得换。这样一来，新件就可以卖钱了。但事故车再怎么修，也成了一辆烂车，修理工则可以把责任全都推到事故上。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp; 自从张宇清学会宰客后，他平均每个月收入2万元左右，最高时一个月收入4万多元。2007年12月中旬，他带着女朋友在南京市白下区某小区按揭买下了一套96平方米的房子。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp;&nbsp;&nbsp; 性命攸关，迷途知返心路太长</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp;&nbsp; 在修车行业干了几年，张宇清对这一行的&ldquo;猫腻&rdquo;越来越清楚了，可以说是千奇百怪，令车主防不胜防，何况很多车主根本就不会设防。 比如机修工故意往机油里放白糖，因为白糖受热后会成黏糊状，却没有任何润滑作用，别人也发现不了，很快就会导致发动机&ldquo;抱瓦&rdquo;，不能正常工作。张宇清刚到45店工作的当天，忽然接到一个电话，是武进市一家修车店打来的，对方说他们介绍一辆车到南京去找张宇清所在的店，一个小时后就到。原来，一条公路上的修车部往往是有联系的，机修工知道放了白糖的汽车最多只能跑百儿八十公里，他们放了糖后．还会打电话告诉下一个维修部做好等那辆车的准备，大家相互介绍&ldquo;生意&rdquo;!</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp; 至于用火碱代替专用的发动机清洗液剂、国产漆代替进口漆，往防冻液里放盐毁坏水箱、私开车主的车去兜风等等就更不用说了。而很多车主对这些做法虽然有所察觉，却没有真凭实据，只得自认倒霉。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp; 真正触动张宇清的是一场车祸。2008年2月12日，一辆黑色帕萨特被拖到店里修理，那车的前部已经被撞得面目全非，挡风玻璃也碎了，里面的人肯定受伤不轻。张宇清仔细一看车牌，记得几天前那车才在他们店里修过，但不是他修的。再一检查车辆，他发现刹车油的颜色不对，一定是里面放了酒精!</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp; 终于出事了!这起车祸的真正祸首是机修工。这是在犯罪啊!但是，由于酒精可以挥发，而且谁也不会用嘴去尝刹车油，所以没有人会想到竟然有人会往刹车油里放酒精。再说，就是有人知道，现在酒精已经挥发了，也是神不知鬼不觉啊!</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp; 张宇清把修车的一些黑幕告诉女朋友，女友对他说：&ldquo;你可千万不能做那种缺德事，那样的钱，赚得再多我也不稀罕!&rdquo;有了女友的这个态度，加上房子已经买了，他的宰客行为收敛了不少。 没想到就在这时，3月18日上午，张宇清的外甥女跟着同学父母的丰田佳美轿车去六合区金牛湖春游，在路上因刹车失灵出了车祸，车上五个人有三人受了重伤，其中张宇清的外甥女骨盆和大腿骨折，可能留下终身残疾。姐姐得知这些，哭得死去活来，差点都要疯了。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp;&nbsp;&nbsp; 外甥女才12岁，像花一样啊!如果造成残疾，她这一辈子怎么办？特别是张宇清一眼看出，是因为在轿车的剥车油中加酒精才造成这起车祸时，他的心灵震撼了：这都是修理工造的孽啊!如果不说，难道任由这种犯罪行为继续下去？这是人命关天的大事啊!如果把这事说出去，自己以后就没法在这一行干了。怎么办？经过几个小时的内心挣扎，张宇清再也忍不住了，他觉得就像是自己害了外甥女，不说出来良心不安。他向交警部门进行举报，并现身说法。说了很多修车行业的黑摹．经对利车油检验．交警部门证实了张宇清说的情况是真实的。那家修车店的老板和维修工被警方带走协助调查。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp; 第三天晚上，张字清在那家4s店里值夜晚班。凌晨l点多，不知从什么地方蹿出几个人，抡起铁棍就将店的门窗砸个稀巴烂。他连忙从后门跑出去，才没有出大事。他想起以前曾有人警告他，干修车这一行就得严守这一行的秘密，所以他知道，一定是自己举报了那家修车店，人家报复他来了。老板听说张宇清把修车行业的很多内幕告诉了警方，很快也找理由将他&ldquo;炒鱿鱼&rdquo;。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;&nbsp; 2008年4月2日接受笔者采访时张宇清表示：&ldquo;修车这个行业的内幕太黑了，赚钱的毒招太多．有不少甚至涉及违法犯罪。如果不加强管理．车主们还不知道要吃多少亏，更有可能会出人命的!以后只要有机会，我还要说，一定要让更多的人知道这里面的黑幕&hellip;&hellip;&rdquo;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: auto; text-align: left; line-height: 1.5; font-size: 14px; ">&nbsp;</p></span></p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/292.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=292</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=292&amp;key=2d10dfbc</trackback:ping></item><item><title>lrf cover tools</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/278.html</link><pubDate>Mon, 23 Feb 2009 10:30:56 +0800</pubDate><guid>http://blog.bigcomic.com/post/278.html</guid><description><![CDATA[<p>1. lrf2lrs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://blog.bigcomic.com/upload/lrf2lrs_03.zip">http://blog.bigcomic.com/upload/lrf2lrs_03.zip</a><br /><br />&nbsp;&nbsp;&nbsp; lrf to lrs .&nbsp; python写的小工具</p><p>2. pylrs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://blog.bigcomic.com/upload/pylrs-1.0.0.zip">http://blog.bigcomic.com/upload/pylrs-1.0.0.zip</a></p><p>&nbsp;&nbsp;&nbsp; python模块, 可以生成lrf</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/278.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=278</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=278&amp;key=78057c71</trackback:ping></item><item><title>History of LRF format</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/277.html</link><pubDate>Mon, 23 Feb 2009 10:24:45 +0800</pubDate><guid>http://blog.bigcomic.com/post/277.html</guid><description><![CDATA[<p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt">The LRF format is a proprietary format by Sony used in their e-readers.The format is still undocumented. Many efforts were done by enthusiasts to understand the format and to make utilities for LRF conversion since appearing Sony Librie (Japaneese version) reader on the market. This review is my personal vision of the history and is limited to the resources I used in my work. LRF conversion is rapidly growing area of the content generation development (inspired by new Sony Reader PRS-500). There are several other resources and wiki pages devoted to the LRF format and tools for conversion; the goal of this page is a review of major achievements for the beginners. This section reflects works done before February 2007, some links may not work. I'm not going to update this page for new resources, please visit forums listed in the Link section for up-to-date information.<o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt">The goal of this page is to provide a reference to the programs that can be used for understanding the LRF format, the program listed here are not the only (and not necessarily the best) way to make lrf content. <o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><b style="mso-bidi-font-weight: normal"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt">Formats<o:p></o:p></span></b></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt">LRF format. This BINARY format used in Sony Librie and Sony PRS-500 Readers. The format is barely documented. Some very limited information can be found at http://www.sven.de/librie/Librie/BBeB . The LRF format can be understood with the python code of lrf2lrs converter and utilities for extracting the objects from LRF files (see below). The LRF can contain text or images, the ability to show images sometimes used by homemade programs with the reference to &quot;picture&quot; LRF (actually this is just simple implementation of one of the features of LRF format). <o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt">LRS (Librie Reader Source) format. LRS is a &quot;source&quot; XML format with the description for the objects used in LRF. This format was introduced in the Book Creator program (commercial program with Japanese interface) by Canon (see below). The format is documented: http://www.y-adagio.com/public/committees/iec_pt62448/1_np(0509)/100_1017e_DC.pdf . LRS files can be generated by either 3 ways: 1) with commercial Book Creator program by Canon; 2) with freeware Book Designer program (see below for more details) 3) with Python lrf2lrs converter by roxfan, Igor Skochinsky and several newly developed utilities available at www.mobileread.com. <o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt">BBeB &quot;Broadband ebook&quot; format by Sony. Another name of LRF and, sometimes, LRS formats.<o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt">Programs useful for understanding the LRF format <o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt">Major programs for understanding the LRF format, listed by date: <o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt">1. Book Creator Commercial program by Canon. First mentioned in yahoo Librie group in June 2004, see post #18). The program has Japanese interface. Since that time the development of homemade LRF content was started. First, many affords were done to make English version of Book Creator (see Librie yahoo group); Second, some homebrew programs use XYLogParser.dll (with Lrs2lrf wrapper by roxfan) to create LRF files from LRS source; Third, reverse engineering of LRF format was started to develop programs independent from XYLogParser.dll. <o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt">2. Makelrf program by scythic (first introduced in yahoo librie group in October, 2004). The program comes with C-code and available in the File section of Librie group. The program allows to create Lrf files from the text files with support of the images. The program cannot create rich lrf files (only basic objects are supported), but it is hard to underestimated the progress archived with the program. Till now makelrf is widely used in many other programs as an engine for creation either simple text LRF or image-based LRF. Until recently makelrf was used in BookDesigner program (in &quot;simple&quot; conversion mode); and JAP programs to generate image-based LRFs. <o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt">3. LRFParser by roxfan (yahoo Librie group, November 2004, comes with C-source). The program decompiles LRF files to the objects, including TOC, header and compressed streams. To my knowledge, LRFparser is the first program where complex LRF objects and majority of tags were understood.<o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt">4. lrf2lrs (first version signed by roxan, February 2006; yahoo Librie group); the latest versions (signed by roxfan, Igor Skochinsky) are available at www.mobileread.com (Sony Portable Reader - Reader Developer's Corner - Lrf2Lrs thread, posts by igorsk). (I believe that roxfan=Igor Skorchinsky=igorsk). With the program the LRF files can be converted to the LRS files. Up to date the source of this Python program is the major source of information on LRF objects and tags. Almost all possible LRF objects and tags are supported by the program.<o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt">5. LRFunpack (by me, available at download section of this site, November 2006). NET2.0 C# application for extracting objects from LRF files with some translation of the tags and description of the streams. Creates both dump hex files for each of the object together with the text files with some decryption. I was using this program to understand the LRF format. The advantage of this program - it never stops decompiling even if tag is unknown. Some example of decompiled lrf can be found at download section. Sorry, no source available. <o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt">----------- <o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt">I did not mention Java tools, because I never tried them myself. Please have a look at the forums of the sites listed in the Link section. I believe the most significant contributions are flatLrf (http://monalipse.sourceforge.jp/tmp/lrf/, January 2005) and LRFParser.java (by Scotty1024, May 2005, Librie yahoo group). FlatLrf is Java application to create lrf from html files; LRFParser.java is Java version of LRFParser by roxfan.<o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt">BookDesigner (Wiki page) (by Valerii Woizechovsky (aka vvv))). This program is an universal program for conversion between many formats, reading and ebook creation. The program creates LRS file, than the LRS file is converted to LRF with external third-party converters (makelrf, lrs2lrf , LRSparser by AlexXF, the latest version uses my MSH_Lrsparser). The strong side of the BookDesigner for understanding the LRF format is ability to generate custom LRS together with corresponding LRF file for further analysis.<o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt">LRF conversion utilities <o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-themecolor: text1; mso-font-kerning: 0pt">Please refer to the Wiki page and the link section for recent progress on content generation. Recently Sony launched site for the developers at www. prslabs.com. Unfortunately there is almost no new information. The LRS format specification is given (the one mentioned above), the XYLogParser.dll (almost the same to the discussed above, it is also very slow), and the description of the interface around the XYLogparser.dll.<o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><o:p><font face="Calibri" size="3">&nbsp;</font></o:p></span></p><p>&nbsp;<a style="color: #00c; text-decoration: underline" href="http://www.msh-tools.com/ebook/lrfformat.html">http://www.msh-tools.com/ebook/lrfformat.html</a></p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/277.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=277</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=277&amp;key=fd878d63</trackback:ping></item><item><title>Lrf file format</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/276.html</link><pubDate>Mon, 23 Feb 2009 10:21:36 +0800</pubDate><guid>http://blog.bigcomic.com/post/276.html</guid><description><![CDATA[<p class="vspace">A LRF file consists of a header, a number of objects and an object index. All values are in Intel (LSB first) order.</p><div class="vspace">&nbsp;</div><h2>Header</h2><p><table border="1">    <tbody>        <tr>            <td align="center">Offset (hex)</td>            <td align="center">Size(bytes)</td>            <td align="center">Name/meaning</td>            <td align="center">Example value</td>        </tr>        <tr>            <td align="center">0</td>            <td align="center">8</td>            <td align="center">LRF Signature</td>            <td align="center">4C 00 52 00 46 00 00 00 = &quot;LRF&quot; in Unicode</td>        </tr>        <tr>            <td align="center">8</td>            <td align="center">2</td>            <td align="center">version?</td>            <td align="center">999 in most files</td>        </tr>        <tr>            <td align="center">A</td>            <td align="center">2</td>            <td align="center">&quot;Psuedo-Encryption&quot; key byte</td>            <td align="center">48</td>        </tr>        <tr>            <td align="center">0C</td>            <td align="center">4</td>            <td align="center"><span class="wikiword"><a class="wikilink" href="http://www.sven.de/librie/Librie/RootObjectID">RootObjectID</a></span></td>            <td align="center">0x0044</td>        </tr>        <tr>            <td align="center">10</td>            <td align="center">8</td>            <td align="center"><span class="wikiword"><a class="wikilink" href="http://www.sven.de/librie/Librie/NumberOfObjects">NumberOfObjects</a></span></td>            <td align="center">342</td>        </tr>        <tr>            <td align="center">18</td>            <td align="center">8</td>            <td align="center"><span class="wikiword"><a class="wikilink" href="http://www.sven.de/librie/Librie/ObjectIndexOffset">ObjectIndexOffset</a></span></td>            <td align="center">0x00093440</td>        </tr>        <tr>            <td align="center">20</td>            <td align="center">4</td>            <td align="center">unknown</td>            <td align="center">0</td>        </tr>        <tr>            <td align="center">24</td>            <td align="center">1</td>            <td align="center">Flags (16 - back to front, 1 = front to back)</td>            <td align="center">16</td>        </tr>        <tr>            <td align="center">25</td>            <td align="center">1</td>            <td align="center">unknown (padding?)</td>            <td align="center">0</td>        </tr>        <tr>            <td align="center">26</td>            <td align="center">2</td>            <td align="center">unknown</td>            <td align="center">1600</td>        </tr>        <tr>            <td align="center">28</td>            <td align="center">2</td>            <td align="center">unknown (padding?)</td>            <td align="center">0</td>        </tr>        <tr>            <td align="center">2A</td>            <td align="center">2</td>            <td align="center">Height?</td>            <td align="center">600</td>        </tr>        <tr>            <td align="center">2C</td>            <td align="center">2</td>            <td align="center">Width?</td>            <td align="center">800</td>        </tr>        <tr>            <td align="center">2E</td>            <td align="center">1</td>            <td align="center">unknown</td>            <td align="center">24</td>        </tr>        <tr>            <td align="center">2F</td>            <td align="center">1</td>            <td align="center">unknown (padding?)</td>            <td align="center">0</td>        </tr>        <tr>            <td align="center">30</td>            <td align="center">0x14</td>            <td align="center">unknown</td>            <td align="center">zeroes</td>        </tr>        <tr>            <td align="center">44</td>            <td align="center">4</td>            <td align="center">Object ID of only <span class="wikiword"><a class="wikilink" href="http://www.sven.de/librie/Librie/PlaneStream">PlaneStream</a></span> (0x1E) object</td>            <td align="center">0x0042</td>        </tr>        <tr>            <td align="center">48</td>            <td align="center">4</td>            <td align="center">unknown</td>            <td align="center">0x1536</td>        </tr>        <tr>            <td align="center">4C</td>            <td align="center">2</td>            <td align="center"><span class="wikiword"><a class="wikilink" href="http://www.sven.de/librie/Librie/XMLCompSize">XMLCompSize</a></span></td>            <td align="center">0x035C</td>        </tr>    </tbody></table></p><p class="vspace">Next two fields are only present if version&gt;=800.</p><p><table border="1">    <tbody>        <tr>            <td align="center">4E</td>            <td align="center">2</td>            <td align="center">unknown</td>            <td align="center">0x0014</td>        </tr>        <tr>            <td align="center">50</td>            <td align="center">4</td>            <td align="center"><span class="wikiword"><a class="wikilink" href="http://www.sven.de/librie/Librie/GifSize">GifSize</a></span></td>            <td align="center">0x03F2</td>        </tr>    </tbody></table></p><p class="vspace">Immediately follows the compressed XML metainfo, of size <span class="wikiword"><a class="wikilink" href="http://www.sven.de/librie/Librie/XMLCompSize">XMLCompSize</a></span>. First dword of it is the size of uncompressed data, the rest is zlib compressed unicode XML.</p><p class="vspace">If version&gt;=800, the gif thumbnail follows, of size <span class="wikiword"><a class="wikilink" href="http://www.sven.de/librie/Librie/GifSize">GifSize</a></span>.</p><div class="vspace">&nbsp;</div><h2>Object index</h2><p>Offset to the index is specified by the <span class="wikiword"><a class="wikilink" href="http://www.sven.de/librie/Librie/ObjectIndexOffset">ObjectIndexOffset</a></span> in the header, and number of entries is <span class="wikiword"><a class="wikilink" href="http://www.sven.de/librie/Librie/NumberOfObjects">NumberOfObjects</a></span>.</p><p class="vspace">Each index entry has the following layout:</p><p><table border="1">    <tbody>        <tr>            <td align="center">Offset (hex)</td>            <td align="center">Size(bytes)</td>            <td align="center">Name/meaning</td>            <td align="center">Example value</td>        </tr>        <tr>            <td align="center">00</td>            <td align="center">4</td>            <td align="center">id</td>            <td align="center">0x32</td>        </tr>        <tr>            <td align="center">04</td>            <td align="center">4</td>            <td align="center">offset</td>            <td align="center">0x07B0</td>        </tr>        <tr>            <td align="center">08</td>            <td align="center">4</td>            <td align="center">size</td>            <td align="center">0x44</td>        </tr>        <tr>            <td align="center">0C</td>            <td align="center">4</td>            <td align="center">reserved?</td>            <td align="center">0</td>        </tr>    </tbody></table></p><div class="vspace">&nbsp;</div><h2>Objects</h2><p>See <span class="wikiword"><a class="wikilink" href="http://www.sven.de/librie/Librie/LrfObject">LrfObject</a></span> [http://buycialis.cc<a class="apprlink" href="http://www.sven.de/librie/Librie/LrfFormat?action=approvesites">(approve sites)</a> buy cialis online] [http://buycialis.cc<a class="apprlink" href="http://www.sven.de/librie/Librie/LrfFormat?action=approvesites">(approve sites)</a> buy cialis] http://buycialis.cc buy cialis online<a class="apprlink" href="http://www.sven.de/librie/Librie/LrfFormat?action=approvesites">(approve sites)</a></p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/276.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=276</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=276&amp;key=120a7611</trackback:ping></item><item><title>file format</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/275.html</link><pubDate>Mon, 23 Feb 2009 10:09:51 +0800</pubDate><guid>http://blog.bigcomic.com/post/275.html</guid><description><![CDATA[<p><a title="http://en.wikipedia.org/wiki/Alphabetical_list_of_file_extensions#L" href="http://en.wikipedia.org/wiki/Alphabetical_list_of_file_extensions#L">http://en.wikipedia.org/wiki/Alphabetical_list_of_file_extensions#L</a></p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/275.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=275</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=275&amp;key=960200b1</trackback:ping></item><item><title>Centos5.2 下的 vsftpd 虚拟用户</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/273.html</link><pubDate>Sun, 22 Feb 2009 21:11:20 +0800</pubDate><guid>http://blog.bigcomic.com/post/273.html</guid><description><![CDATA[<p>安装步骤基本和Ubuntu下差不多, 只不过需要多装一个pam_userdb, 我是yum装的 <font face="Courier New">yum install db4-utils</font></p><p>ubuntu下参考之前的文章: <a title="http://blog.bigcomic.com/post/241.html" href="http://blog.bigcomic.com/post/241.html">http://blog.bigcomic.com/post/241.html</a></p><p>有一点不同的是ubuntu下的pam日志在 /var/log/auth.log.&nbsp; 而centos5.2是在 /var/log/secure</p><p>&nbsp;</p><p>EOF</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/273.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=273</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=273&amp;key=3e038bec</trackback:ping></item><item><title>侧边栏工具 TopWords</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/272.html</link><pubDate>Fri, 20 Feb 2009 12:55:47 +0800</pubDate><guid>http://blog.bigcomic.com/post/272.html</guid><description><![CDATA[<p>基本功能写出来了, 没有时间优化, 凑合着用先...</p> <p><a href="http://blog.bigcomic.com/upload/TopWords.gadget.rar" target="_blank">下载TopWords</a></p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/272.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=272</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=272&amp;key=7018bc34</trackback:ping></item><item><title>解决/dev/fb0无法打开的问题</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/266.html</link><pubDate>Thu, 12 Feb 2009 16:45:28 +0800</pubDate><guid>http://blog.bigcomic.com/post/266.html</guid><description><![CDATA[<div><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> 最近要在Linux做基于frame Buffer的图形显示，不论我在独立分区的Linux FC6系统中，还是在装有Red hat9的VPC中，都无法打开/dev/fb0。从网上找了很多资料，都没能解决。经过几天的的郁闷之后，终于解决了这个问题。先记录如下：</span></span></div><div><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> 1、首先确认对Frame Buffer的支持是否编译到Linux的内核中。在安装的Linux中，默认都会把这个支持打开编译到内核中。但是如果自己重新编译了内核，或者升级内核，得确认把Frame Buffer的支持编入内核，并且还要把Console display driver support编译到内核中，还要把Logo&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">configuration编译到内核中。这些选项都在Device drivers下的graphics support选项下。</span></span></div><div><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> 2、在启动项中打开对Frame Buffer的支持。由于虽然把对Frame Buffer的支持编译到内核中了，但是默认下是没有打开的。故要修改/boot/grub/menu.lst文件。在该文件的kernel那一行后面加上vga=0xXXX，0xXXX表示的是屏幕的分辨率和色彩数。</span></span></div><div><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> 其中vga=0x后面的数值可以从下表中查出。<br /></span></span></div><div><table style="width: 429px; height: 103px" cellspacing="1" cellpadding="1" width="429" border="1">    <tbody>        <tr>            <td><span style="font-size: larger"><span style="font-family: 宋体">色彩数</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">640 X 480</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">800X600</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">1024X768</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">1280X1024</span></span></td>        </tr>        <tr>            <td><span style="font-size: larger"><span style="font-family: 宋体">256</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">0x301</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">0x303</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">0x305</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">0x307</span></span></td>        </tr>        <tr>            <td><span style="font-size: larger"><span style="font-family: 宋体">32k</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">0x310</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">0x313</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">0x316</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">0x319</span></span></td>        </tr>        <tr>            <td><span style="font-size: larger"><span style="font-family: 宋体">64k</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">0x311</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">0x314</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">0x317</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">0x31A</span></span></td>        </tr>        <tr>            <td><span style="font-size: larger"><span style="font-family: 宋体">16M</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">0x312</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">0x315</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">0x318</span></span></td>            <td><span style="font-size: larger"><span style="font-family: 宋体">0x31B</span></span></td>        </tr>    </tbody></table></div><div><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> 我原先的/boot/grub/menu.lst文件如下:</span></span></div><div><span style="font-size: larger"><span style="font-family: 宋体"># grub.conf generated by anaconda<br />#<br /># Note that you do not have to rerun grub after making changes to this file<br /># NOTICE:&nbsp;</span></span><font face="宋体"><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> You have a /boot partition.&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> This means that<br />#&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> all kernel and initrd paths are relative to /boot/, eg.<br />#&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> root (hd0,0)<br />#&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> kernel /vmlinuz-version ro root=/dev/hda3<br />#&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> initrd /initrd-version.img<br />#boot=/dev/hda<br />default=0<br />timeout=10<br />splashimage=(hd0,0)/grub/splash.xpm.gz<br />title Red Hat Linux (2.6.18)<br />&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> root (hd0,0)<br />&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> kernel /vmlinuz-2.6.18 ro root=LABEL=/&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"><br />&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> initrd /initrd-2.6.18.img<br />title Red Hat Linux (2.4.20-8)<br />&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> root (hd0,0)<br />&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> kernel /vmlinuz-2.4.20-8 ro root=LABEL=/&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"><br />&nbsp;</span></span><wbr></wbr></font><span style="font-size: larger"><span style="font-family: 宋体"> initrd /initrd-2.4.20-8.img</span></span></div><div><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> 因为我对red hat9升级了一个2.6.18的内核，故有两个启动项。修改后，如下：</span></span></div><div><span style="font-size: larger"><span style="font-family: 宋体"><font face="宋体"># grub.conf generated by anaconda<br />#<br /># Note that you do not have to rerun grub after making changes to this file<br /># NOTICE:&nbsp;</font></span></span><font face="宋体"><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> You have a /boot partition.&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> This means that<br />#&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> all kernel and initrd paths are relative to /boot/, eg.<br />#&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> root (hd0,0)<br />#&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> kernel /vmlinuz-version ro root=/dev/hda3<br />#&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr></font><span style="font-size: larger"><span style="font-family: 宋体"><font face="宋体"> initrd /initrd-version.img<br />#boot=/dev/hda<br />default=0</font></span></span></div><div><span style="font-size: larger"><span style="font-family: 宋体">timeout=10<br />splashimage=(hd0,0)/grub/splash.xpm.gz<br />title Red Hat Linux (2.6.18)<br />&nbsp;</span></span><font face="宋体"><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> root (hd0,0)<br />&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> <font color="#ff0000">kernel /vmlinuz-2.6.18 ro root=LABEL=/ vga=0x311</font><br />&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> initrd /initrd-2.6.18.img<br />title Red Hat Linux (2.4.20-8)<br />&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> root (hd0,0)<br />&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> <font color="#ff0000">kernel /vmlinuz-2.4.20-8 ro root=LABEL=/ vga=0x311</font><br />&nbsp;</span></span><wbr></wbr></font><span style="font-size: larger"><span style="font-family: 宋体"> initrd /initrd-2.4.20-8.img</span></span></div><div><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr></div><div><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> 3、重启系统。然后运行cat /dev/fb0，如果发现有一堆乱码输出在屏幕上，则表示找到了/dev/fb0这个设备。如果没有，则可能是你的显卡不支持。</span></span></div><div><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体">&nbsp;</span></span><wbr></wbr><span style="font-size: larger"><span style="font-family: 宋体"> 通过上述操作以后，我的虚拟机中的Linux和独立分区装的Linux都可以打开/dev/fb0了。最后还说一句，打开/dev/fb0是在控制台下打开，在XWindow界面下能打开，但是操作屏幕缓存区画图的时候，会不正确。</span></span></div>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/266.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=266</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=266&amp;key=b478552c</trackback:ping></item><item><title>用mysqlslap进行MySQL压力测试</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/258.html</link><pubDate>Fri, 05 Dec 2008 14:30:30 +0800</pubDate><guid>http://blog.bigcomic.com/post/258.html</guid><description><![CDATA[<blockquote> <p>–auto-generate-sql, -a<br>自动生成测试表和数据 <p>–auto-generate-sql-load-type=type<br>测试语句的类型。取值包括：read，key，write，update和mixed(默认)。 <p>–number-char-cols=N, -x N<br>自动生成的测试表中包含多少个字符类型的列，默认1 <p>–number-int-cols=N, -y N<br>自动生成的测试表中包含多少个数字类型的列，默认1 <p>–number-of-queries=N<br>总的测试查询次数 <p>–query=name,-q<br>使用自定义脚本执行测试，例如可以调用自定义的一个存储过程或者sql语句来执行测试。 <p>–create-schema<br>测试的schema，MySQL中schema也就是database <p>–commint=N<br>多少条DML后提交一次 <p>–compress, -C<br>如果服务器和客户端支持都压缩，则压缩信息传递 <p>–concurrency=N, -c N<br>并发量，也就是模拟多少个客户端同时执行select。可指定多个值，以逗号或者–delimiter参数指定的值做为分隔符 <p>–engine=engine_name, -e engine_name<br>创建测试表所使用的存储引擎，可指定多个 <p>–iterations=N, -i N<br>测试执行的迭代次数 <p>–detach=N<br>执行N条语句后断开重连 <p>–debug-info, -T<br>打印内存和CPU的信息 <p>–only-print<br>只打印测试语句而不实际执行 <p>测试的过程需要生成测试表，插入测试数据，这个mysqlslap可以自动生成，默认生成一个mysqlslap的schema，如果已经存在则先 删除，这里要注意了，不要用–create-schema指定已经存在的库，否则后果可能很严重。可以用–only-print来打印实际的测试过程： <p>$mysqlslap -a --only-print<br>DROP SCHEMA IF EXISTS `mysqlslap`;<br>CREATE SCHEMA `mysqlslap`;<br>use mysqlslap;<br>CREATE TABLE `t1` (intcol1 INT(32) ,charcol1 VARCHAR(128));<br>INSERT INTO t1 VALUES (1804289383,'mxvtvmC9127qJNm06sGB8R92q2j7vTiiITRDGXM9ZLzkdekbWtmXKwZ2qG1llkRw5m9DHOFilEREk3q7oce8O3BEJC0woJsm6uzFAEynLH2xCsw1KQ1lT4zg9rdxBL');<br>...<br>SELECT intcol1,charcol1 FROM t1;<br>INSERT INTO t1 VALUES (364531492,'qMa5SuKo4M5OM7ldvisSc6WK9rsG9E8sSixocHdgfa5uiiNTGFxkDJ4EAwWC2e4NL1BpAgWiFRcp1zIH6F1BayPdmwphatwnmzdwgzWnQ6SRxmcvtd6JRYwEKdvuWr');<br>DROP SCHEMA IF EXISTS `mysqlslap`; <p>可以看到最后由删除一开始创建的schema的动作，整个测试完成后不会在数据库中留下痕迹。假如我们执行一次测试，分别50和100个并发，执行1000次总查询，那么： <p>$mysqlslap -a --concurrency=50,100 --number-of-queries 1000 --debug-info<br>Benchmark<br>Average number of seconds to run all queries: 0.375 seconds<br>Minimum number of seconds to run all queries: 0.375 seconds<br>Maximum number of seconds to run all queries: 0.375 seconds<br>Number of clients running queries: 50<br>Average number of queries per client: 20<br>Benchmark<br>Average number of seconds to run all queries: 0.453 seconds<br>Minimum number of seconds to run all queries: 0.453 seconds<br>Maximum number of seconds to run all queries: 0.453 seconds<br>Number of clients running queries: 100<br>Average number of queries per client: 10<br>User time 0.29, System time 0.11<br>Maximum resident set size 0, Integral resident set size 0<br>Non-physical pagefaults 4032, Physical pagefaults 0, Swaps 0<br>Blocks in 0 out 0, Messages in 0 out 0, Signals 0<br>Voluntary context switches 7319, Involuntary context switches 681 <p>上结果可以看出，50和100个并发分别得到一次测试结果(Benchmark)，并发数越多，执行完所有查询的时间越长。为了准确起见，可以多迭代测试几次: <p>$ mysqlslap -a --concurrency=50,100 --number-of-queries 1000 --iterations=5 --debug-info <br>Benchmark<br>Average number of seconds to run all queries: 0.380 seconds<br>Minimum number of seconds to run all queries: 0.377 seconds<br>Maximum number of seconds to run all queries: 0.385 seconds<br>Number of clients running queries: 50<br>Average number of queries per client: 20<br>Benchmark<br>Average number of seconds to run all queries: 0.447 seconds<br>Minimum number of seconds to run all queries: 0.444 seconds<br>Maximum number of seconds to run all queries: 0.451 seconds<br>Number of clients running queries: 100<br>Average number of queries per client: 10<br>User time 1.44, System time 0.67<br>Maximum resident set size 0, Integral resident set size 0<br>Non-physical pagefaults 17922, Physical pagefaults 0, Swaps 0<br>Blocks in 0 out 0, Messages in 0 out 0, Signals 0<br>Voluntary context switches 36796, Involuntary context switches 4093 <p>测试同时不同的存储引擎的性能进行对比： <p>$ mysqlslap -a --concurrency=50,100 --number-of-queries 1000 --iterations=5 --engine=myisam,innodbmysqlslap -a --concurrency=50,100 --number-of-queries 1000 --iterations=5 --engine=myisam,innodb --debug-info<br>Benchmark<br>Running for engine myisam<br>Average number of seconds to run all queries: 0.200 seconds<br>Minimum number of seconds to run all queries: 0.188 seconds<br>Maximum number of seconds to run all queries: 0.210 seconds<br>Number of clients running queries: 50<br>Average number of queries per client: 20<br>Benchmark<br>Running for engine myisam<br>Average number of seconds to run all queries: 0.238 seconds<br>Minimum number of seconds to run all queries: 0.228 seconds<br>Maximum number of seconds to run all queries: 0.251 seconds<br>Number of clients running queries: 100<br>Average number of queries per client: 10<br>Benchmark<br>Running for engine innodb<br>Average number of seconds to run all queries: 0.375 seconds<br>Minimum number of seconds to run all queries: 0.370 seconds<br>Maximum number of seconds to run all queries: 0.379 seconds<br>Number of clients running queries: 50<br>Average number of queries per client: 20<br>Benchmark<br>Running for engine innodb<br>Average number of seconds to run all queries: 0.443 seconds<br>Minimum number of seconds to run all queries: 0.440 seconds<br>Maximum number of seconds to run all queries: 0.447 seconds<br>Number of clients running queries: 100<br>Average number of queries per client: 10<br>User time 2.83, System time 1.66<br>Maximum resident set size 0, Integral resident set size 0<br>Non-physical pagefaults 34692, Physical pagefaults 0, Swaps 0<br>Blocks in 0 out 0, Messages in 0 out 0, Signals 0<br>Voluntary context switches 87306, Involuntary context switches 10326</p></blockquote>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/258.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=258</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=258&amp;key=a360e8f9</trackback:ping></item><item><title>DRBD笔记</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/251.html</link><pubDate>Thu, 04 Dec 2008 23:57:19 +0800</pubDate><guid>http://blog.bigcomic.com/post/251.html</guid><description><![CDATA[<p></p> <p>一、主要功能 <p>&nbsp;&nbsp;&nbsp; DRBD实际上是一种块设备的实现,主要被用于Linux平台下的高可用(HA)方案之中。他是有内核模块和相关程序而组成，通过网络通信来同步镜像整个设备，有点类似于一个网络RAID的功能。也就是说当你将数据写入本地的DRBD设备上的文件系统时,数据会同时被发送到网络中的另外一台主机之上，并以完全相同的形式记录在一个文件系统中（实际上文件系统的创建也是由DRBD的同步来实现的）。本地节点（主机）与远程节点（主机）的数据可以保证实时的同步，并保证IO的一致性。所以当本地节点的主机出现故障时,远程节点的主机上还会保留有一份完全相同的数据,可以继续使用，以达到高可用的目的。 <p>&nbsp;&nbsp;&nbsp; 在高可用(HA)解决方案中使用DRBD的功能,可以代替使用一个共享盘阵存储设备。因为数据同时存在于本地主机和远程主机上,在遇到需要切换的时候,远程主机只需要使用它上面的那份备份数据,就可以继续提供服务了。 <p>二、底层设备支持 <p>&nbsp;&nbsp;&nbsp; DRBD需要构建在底层设备之上，然后构建出一个块设备出来。对于用户来说，一个DRBD设备，就像是一块物理的磁盘，可以在商脉内创建文件系统。DRBD所支持的底层设备有以下这些类： <p>&nbsp;&nbsp;&nbsp; 1、一个磁盘，或者是磁盘的某一个分区； <p>&nbsp;&nbsp;&nbsp; 2、一个soft raid 设备； <p>&nbsp;&nbsp;&nbsp; 3、一个LVM的逻辑卷； <p>&nbsp;&nbsp;&nbsp; 4、一个EVMS（Enterprise Volume Management System，企业卷管理系统）的卷； <p>&nbsp;&nbsp;&nbsp; 5、其他任何的块设备。 <p>三、配置简介 <p>&nbsp;&nbsp;&nbsp; 1、全局配置项（global） <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 基本上我们可以做的也就是配置usage-count是yes还是no了，usage-count参数其实只是为了让linbit公司收集目前drbd的使用情况。当drbd在安装和升级的时候会通过http协议发送信息到linbit公司的服务器上面。 <p>&nbsp;&nbsp;&nbsp; 2、公共配置项（common） <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这里的common，指的是drbd所管理的多个资源之间的common。配置项里面主要是配置drbd的所有resource可以设置为相同的参数项，比如protocol，syncer等等。 <p>&nbsp;&nbsp;&nbsp; 3、资源配置项（resource） <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resource项中配置的是drbd所管理的所有资源，包括节点的ip信息，底层存储设备名称，设备大小，meta信息存放方式，drbd对外提供的设备名等等。每一个resource中都需要配置在每一个节点的信息，而不是单独本节点的信息。实际上，在drbd的整个集群中，每一个节点上面的drbd.conf文件需要是完全一致的。 <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 另外，resource还有很多其他的内部配置项： <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; net：网络配置相关的内容，可以设置是否允许双主节点（allow-two-primaries）等。 <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; startup：启动时候的相关设置，比如设置启动后谁作为primary（或者两者都是primary：become-primary-on both） <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; syncer：同步相关的设置。可以设置“重新”同步（re-synchronization）速度（rate）设置，也可以设置是否在线校验节点之间的数据一致性（verify-alg 检测算法有md5，sha1以及crc32等）。数据校验可能是一个比较重要的事情，在打开在线校验功能后，我们可以通过相关命令（drbdadm verify resource_name）来启动在线校验。在校验过程中，drbd会记录下节点之间不一致的block，但是不会阻塞任何行为，即使是在该不一致的block上面的io请求。当不一致的block发生后，drbd就需要有re-synchronization动作，而syncer里面设置的rate项，主要就是用于re-synchronization的时候，因为如果有大量不一致的数据的时候，我们不可能将所有带宽都分配给drbd做re-synchronization，这样会影响对外提提供服务。rate的设置和还需要考虑IO能力的影响。如果我们会有一个千兆网络出口，但是我们的磁盘IO能力每秒只有50M，那么实际的处理能力就只有50M，一般来说，设置网络IO能力和磁盘IO能力中最小者的30%的带宽给re-synchronization是比较合适的（官方说明）。另外，drbd还提供了一个临时的rate更改命令，可以临时性的更改syncer的rate值：drbdsetup /dev/drbd0 syncer -r 100M。这样就临时的设置了re-synchronization的速度为100M。不过在re-synchronization结束之后，你需要通过drbdadm adjust resource_name 来让drbd按照配置中的rate来工作。 <p>五、资源管理 <p>&nbsp;&nbsp;&nbsp; 1、增加resource的大小： <p>&nbsp;&nbsp;&nbsp; 当遇到我们的drbd resource设备容量不够的时候，而且我们的底层设备支持在线增大容量的时候（比如使用lvm的情况下），我们可以先增大底层设备的大小，然后再通过drbdadm resize resource_name来实现对resource的扩容。但是这里有一点需要注意的就是只有在单primary模式下可以这样做，而且需要先在所有节点上都增大底层设备的容量。然后仅在primary节点上执行resize命令。在执行了resize命令后，将触发一次当前primary节点到其他所有secondary节点的re-synchronization。 <p>&nbsp;&nbsp;&nbsp; 如果我们在drbd非工作状态下对底层设备进行了扩容，然后再启动drbd，将不需要执行resize命令（当然前提是在配置文件中没有对disk参数项指定大小），drbd自己会知道已经增大了容量。 <p>&nbsp;&nbsp;&nbsp; 在进行底层设备的增容操作的时候千万不要修改到原设备上面的数据，尤其是drbd的meta信息，否则有可能毁掉所有数据。 <p>&nbsp;&nbsp;&nbsp; 2、收缩resource容量： <p>&nbsp;&nbsp;&nbsp; 容量收缩比扩容操作要危险得多，因为该操作更容易造成数据丢失。在收缩resource的容量之前，必须先收缩drbd设备之上的容量，也就是文件系统的大小。如果上层文件系统不支持收缩，那么resource也没办法收缩容量。 <p>&nbsp;&nbsp;&nbsp; 如果在配置drbd的时候将meta信息配置成internal的，那么在进行容量收缩的时候，千万别只计算自身数据所需要的空间大小，还要将drbd的meta信息所需要的空间大小加上。 <p>&nbsp;&nbsp;&nbsp; 当文件系统收缩好以后，就可以在线通过以下命令来重设resource的大小：drbdadm — –size=***G resize resource_name。在收缩的resource的大小之后，你就可以自行收缩释放底层设备空间（如果支持的话）。 <p>&nbsp;&nbsp;&nbsp; 如果打算停机状态下收缩容量，可以通过以下步骤进行： <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a、在线收缩文件系统 <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b、停用drbd的resource：drbdadm down resourcec_name <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c、导出drbd的metadata信息（在所有节点都需要进行）：drbdadm dump-md resource_name &gt; /path_you_want_to_save/file_name <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; d、在所有节点收缩底层设备 <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e、更改上面dump出来的meta信息的la-size-sect项到收缩后的大小（是换算成sector的数量后的数值） <p>f、如果使用的是internal来配置meta-data信息，则需要重新创建meta-data:drbdadm create-md resource_name <p>g、将之前导出并修改好的meta信息重新导入drbd（摘录自linbit官方网站的一段导入代码）： <p>&nbsp;&nbsp;&nbsp; drbdmeta_cmd=$(drbdadm -d dump-md test-disk) <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ${drbdmeta_cmd/dump-md/restore-md} /path_you_want_to_save/file_name<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; h、启动resource：drbdadm up resource_name <p>六、磁盘损坏 <p>&nbsp;&nbsp;&nbsp; 1、detach resource <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果在resource的disk配置项中配置了on_io_error为pass_on的话，那么drbd在遇到磁盘损坏后不会自己detach底层设备。也就是说需要我们手动执行detach的命令（drbdadm detach resource_name），然后再查看当前各节点的ds信息。可以通过cat /proc/drbd来查看，也可以通过专有命令来查看：drbdadm dstat resource_name。当发现损坏的那方已经是Diskless后，即可。如果我们没有配置on_io_error或者配置成detach的话，那么上面的操作将会由自动进行。 <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 另外，如果磁盘损坏的节点是当前主节点，那么我们需要进行节点切换的操作后再进行上面的操作。 <p>&nbsp;&nbsp;&nbsp; 2、更换磁盘 <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当detach了resource之后，就是更换磁盘了。如果我们使用的是internal的meta-data，那么在换好磁盘后，只需要重新创建mata-data（drbdadm create-md resource_name），再将resource attach上（drbdadm attach resource_name），然后drbd就会马上开始从当前primary节点到本节点的re-synchronisation。数据同步的实时状况可以通过 /proc/drbd文件的内容获得。 <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 不过，如果我们使用的不是internal的meta-data保存方式，也就是说我们的meta-data是保存在resource之外的地方的。那么我们在完成上面的操作（重建meta-data）之后，还需要进行一项操作来触发re-synchnorisation，所需命令为：drbdadm invalidate resource_name 。 <p>七、节点crash（或计划内维护） <p>&nbsp;&nbsp;&nbsp; 1、secondary节点 <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果是secondary接待你crash，那么primary将临时性的与secondary断开连接，cs状态应该会变成WFConnection，也就是等待连接的状态。这时候primary会继续对外提供服务，并在meta-data里面记录下从失去secondary连接后所有变化过的block的信息。当secondary重新启动并连接上primary后，primary –&gt; secondary的re-synchnorisation会自动开始。不过在re-synchnorisation过程中，primary和secondary的数据是不一致状态的。也就是说，如果这个时候primary节点也crash了的话，secondary是没办法切换成primary的。也就是说，如果没有其他备份的话，将丢失所有数据。 <p>&nbsp;&nbsp;&nbsp; 2、primary节点 <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一般情况下，primary的crash和secondary的crash所带来的影响对drbd来说基本上是差不多的。唯一的区别就是需要多操作一步将secondary节点switch成primary节点先对外提供服务。这个switch的过程drbd自己是不会完成的，需要我们人为干预进行一些操作才能完成。当crash的原primary节点修复并重新启动连接到现在的primary后，会以secondary存在，并开始re-synchnorisation这段时间变化的数据。 <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在primary节点crash的情况下，drbd可以保证同步到原secondary的数据的一致性，这样就避免了当primary节点crash之后，secondary因为数据的不一致性而无法wcitch成primary或者即使切换成primary后因为不一致的数据无法提供正常的服务的问题。 <p>&nbsp;&nbsp;&nbsp; 3、节点永久性损坏（需要更换机器或重新安装相关软件的情况） <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当某一个节点因为硬件（或软件）的问题，导致某一节点已经无法再轻易修复并提供服务，也就是说我们所面对的是需要更换主机（或从OS层开始重新安装）的问题。在遇到这样的问题后，我们所需要做的是重新提供一台和原节点差不多的机器，重新开始安装os，安装相关软件，从现有整提供服务的节点上copy出drbd的配置文件（/etc/drbd.conf），创建meta-data信息，然后启动drbd服务，以一个secondary的身份连接到现有的primary上面，后面就会自动开始re-synchnorisation。 <p>八、split brain的处理 <p>&nbsp;&nbsp;&nbsp; split brain实际上是指在某种情况下，造成drbd的两个节点断开了连接，都以primary的身份来运行。当drbd某primary节点连接对方节点准备发送信息的时候如果发现对方也是primary状态，那么会会立刻自行断开连接，并认定当前已经发生split brain了，这时候他会在系统日志中记录以下信息：“Split-Brain detected,dropping connection!”当发生split brain之后，如果查看连接状态，其中至少会有一个是StandAlone状态，另外一个可能也是StandAlone（如果是同时发现split brain状态），也有可能是WFConnection的状态。 <p>&nbsp;&nbsp;&nbsp; 如果我们在配置文件中配置了自动解决split brain（好像linbit不推荐这样做），drbd会自行解决split brain问题，具体解决策略是根据配置中的设置来进行的。 <p>&nbsp;&nbsp;&nbsp; 如果没有配置split brain自动解决方案，我们可以手动解决。首先我们必须要确定哪一边应该作为解决问题后的primary，一旦确定好这一点，那么我们同时也就确定接受丢失在split brain之后另外一个节点上面所做的所有数据变更了。当这些确定下来后，我们就可以通过以下操作来恢复了： <p>&nbsp;&nbsp;&nbsp; a、首先在确定要作为secondary的节点上面切换成secondary并放弃该资源的数据： <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drbdadm secondary resource_name <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drbdadm — –discard-my-data connect resource_name <p>&nbsp;&nbsp;&nbsp; b、在要作为primary的节点重新连接secondary（如果这个节点当前的连接状态为WFConnection的话，可以省略） <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drbdadm connect resource_name <p>&nbsp;&nbsp;&nbsp; 当作完这些动作之后，从新的primary到secondary的re-synchnorisation会自动开始。 <p>八、meta data存放地点的比较 <p>&nbsp;&nbsp;&nbsp; 1、internal meta-data（meta-data和数据存放在同一个底层设备之上） <p>&nbsp;&nbsp;&nbsp; 优点：一旦meta-data创建之后，就和实际数据绑在了一起，在维护上会更简单方便，不用担心meta-data会因为某些操作而丢失。另外在硬盘损坏丢失数据的同时，meta-data也跟着一起丢失，当更换硬盘之后，只需要执行重建meta-data的命令即可，丢失的数据会很容易的从其他节点同步过来。 <p>&nbsp;&nbsp;&nbsp; 缺点：如果底层设备是单一的磁盘，没有做raid，也不是lvm等，那么可能会造成性能影响。因为每一次写io都需要更新meta-data里面的信息，那么每次写io都会有两次，而且肯定会有磁头的较大寻道移动，因为meta-data都是记录在dice设备的最末端的，这样就会造成写io的性能降低。 <p>&nbsp;&nbsp;&nbsp; 2、external meta data（meta-data存放在独立的，与存放数据的设备分开的设备之上） <p>&nbsp;&nbsp;&nbsp; 优点：与internal meta-data的缺点完全相对，可以解决写io的争用问题。 <p>&nbsp;&nbsp;&nbsp; 缺点：由于meta-data存放在与数据设备分开的地方，就意味着当磁盘损坏更换磁盘之后，必须手动发起全量同步的操作。也就是管理维护会稍微麻烦那么一点点，很小的一点点。 <p>&nbsp;&nbsp;&nbsp; 如果我们希望在已经存在数据的设备上面建立drbd的资源，并且不希望丢失该设备上面的数据，又没办法增大底层设备的容量，而且上层文件系统又没办法收缩的话，我们就只能将meta data创建成external方式。</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/251.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=251</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=251&amp;key=bc24301b</trackback:ping></item><item><title>MySQL查询缓存机制</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/257.html</link><pubDate>Thu, 04 Dec 2008 16:41:05 +0800</pubDate><guid>http://blog.bigcomic.com/post/257.html</guid><description><![CDATA[<p>缓存机制简单的说就是缓存sql文本及查询结果，如果运行相同的sql，服务器直接从缓存中取到结果，而不需要再去解析和执行sql。如果表更改了，那么使用这个表的所有缓冲查询将不再有效，查询缓存值的相关条目被清空。更改指的是表中任何数据或是结构的改变，包括INSERT、UPDATE、DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE等，也包括那些映射到改变了的表的使用MERGE表的查询。显然，这对于频繁更新的表，查询缓存是不适合的，而对于一些不常改变数据且有大量相同sql查询的表，查询缓存会节约很大的性能。<br>查询必须是完全相同的(逐字节相同)才能够被认为是相同的。另外，同样的查询字符串由于其它原因可能认为是不同的。使用不同的数据库、不同的协议版本或者不同 默认字符集的查询被认为是不同的查询并且分别进行缓存。 <p>下面sql查询缓存认为是不同的：<br>SELECT * FROM tbl_name<br>Select * from tbl_name<br>查询缓存相关参数 <p>mysql&gt; SHOW VARIABLES LIKE '%query_cache%';<br>+------------------------------+---------+<br>| Variable_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Value&nbsp;&nbsp; |<br>+------------------------------+---------+<br>| have_query_cache&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | YES&nbsp;&nbsp;&nbsp;&nbsp; | --查询缓存是否可用<br>| query_cache_limit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | 1048576 | --可缓存具体查询结果的最大值<br>| query_cache_min_res_unit&nbsp;&nbsp;&nbsp;&nbsp; | 4096&nbsp;&nbsp;&nbsp; | <br>| query_cache_size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | 599040&nbsp; | --查询缓存的大小<br>| query_cache_type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | ON&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | --阻止或是支持查询缓存<br>| query_cache_wlock_invalidate | OFF&nbsp;&nbsp;&nbsp;&nbsp; | <br>+------------------------------+---------+ <p>下面是一个简单的例子： <p>[mysql@csdba1850 ~]$ mysql -u root -p<br>Enter password: <br>Welcome to the MySQL monitor.&nbsp; Commands end with ; or \g.<br>Your MySQL connection id is 3<br>Server version: 5.0.45-community MySQL Community Edition (GPL)<br>Type 'help;' or '\h' for help. Type '\c' to clear the buffer.<br>mysql&gt; set global query_cache_size = 600000; --设置缓存内存<br>Query OK, 0 rows affected (0.00 sec)<br>mysql&gt; set session query_cache_type = ON; --开启查询缓存<br>Query OK, 0 rows affected (0.00 sec)<br>mysql&gt; use test<br>Reading table information for completion of table and column names<br>You can turn off this feature to get a quicker startup with -A<br>Database changed<br>mysql&gt; show tables;<br>+----------------+<br>| Tables_in_test |<br>+----------------+<br>| animals&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br>| person&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br>+----------------+<br>5 rows in set (0.00 sec)<br>mysql&gt; select count(*) from animals;<br>+----------+<br>| count(*) |<br>+----------+<br>|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6 | <br>+----------+<br>1 row in set (0.00 sec)<br>--Qcache_hits表示sql查询在缓存中命中的累计次数，是累加值。<br>mysql&gt; SHOW STATUS LIKE 'Qcache_hits';<br>+---------------+-------+<br>| Variable_name | Value |<br>+---------------+-------+<br>| Qcache_hits&nbsp;&nbsp; | 0&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp; --0次<br>+---------------+-------+<br>8 rows in set (0.00 sec)<br>mysql&gt;&nbsp; select count(*) from animals;<br>+----------+<br>| count(*) |<br>+----------+<br>|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6 | <br>+----------+<br>1 row in set (0.00 sec)<br>mysql&gt;&nbsp; SHOW STATUS LIKE 'Qcache%';<br>+---------------+-------+<br>| Variable_name | Value |<br>+---------------+-------+<br>| Qcache_hits&nbsp;&nbsp; | 1&nbsp;&nbsp;&nbsp;&nbsp; | --表示sql在缓存中直接得到结果，不需要再去解析<br>+---------------+-------+<br>8 rows in set (0.00 sec)<br>mysql&gt; select count(*) from animals;<br>+----------+<br>| count(*) |<br>+----------+<br>|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6 | <br>+----------+<br>1 row in set (0.00 sec)<br>mysql&gt; select count(*) from animals;<br>+----------+<br>| count(*) |<br>+----------+<br>|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6 | <br>+----------+<br>1 row in set (0.00 sec)<br>mysql&gt; SHOW STATUS LIKE 'Qcache_hits';<br>+---------------+-------+<br>| Variable_name | Value |<br>+---------------+-------+<br>| Qcache_hits&nbsp;&nbsp; | 3&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp; --上面的sql也是是从缓存中直接取到结果<br>+---------------+-------+<br>1 row in set (0.00 sec)<br>mysql&gt; insert into animals select 9,'testsds' ; --插入数据后，跟这个表所有相关的sql缓存就会被清空掉<br>Query OK, 1 row affected (0.00 sec)<br>Records: 1&nbsp; Duplicates: 0&nbsp; Warnings: 0<br>mysql&gt; select count(*) from animals;<br>+----------+<br>| count(*) |<br>+----------+<br>|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7 | <br>+----------+<br>1 row in set (0.00 sec)<br>mysql&gt; SHOW STATUS LIKE 'Qcache_hits';<br>+---------------+-------+<br>| Variable_name | Value |<br>+---------------+-------+<br>| Qcache_hits&nbsp;&nbsp; | 3&nbsp;&nbsp;&nbsp; |&nbsp; --还是等于3，说明上一条sql是没有直接从缓存中直接得到的<br>+---------------+-------+<br>1 row in set (0.00 sec)<br>mysql&gt; select count(*) from animals;<br>+----------+<br>| count(*) |<br>+----------+<br>|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7 | <br>+----------+<br>1 row in set (0.00 sec)<br>mysql&gt; SHOW STATUS LIKE 'Qcache_hits'; <br>+---------------+-------+<br>| Variable_name | Value |<br>+---------------+-------+<br>| Qcache_hits&nbsp;&nbsp; | 4&nbsp;&nbsp;&nbsp;&nbsp; | <br>+---------------+-------+<br>1 row in set (0.00 sec)</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/257.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=257</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=257&amp;key=228397ba</trackback:ping></item><item><title>Heartbeat的切换策略-积分统计方法</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/253.html</link><pubDate>Wed, 03 Dec 2008 15:59:47 +0800</pubDate><guid>http://blog.bigcomic.com/post/253.html</guid><description><![CDATA[<p>在V2的Heartbeat中，为了将资源的监控和切换结合起来，同时支持多节点集群，Heartbeat提供了一种积分策略来控制各个资源在集群中各节点之间的切换策略。通过该积分机制，计算出各节点的的总分数，得分最高者将成为active状态来管理某个（或某组）资源。 <p>如果在CIB的配置文件中不做出任何配置的话，那么每一个资源的初始分数（resource-stickiness）都会是默认的0，而且每一个资源在每次失败之后所减掉的分数（resource-failure-stickiness）也是0。如此的话，一个资源不论他失败多少次，heartbeat都只是执行restart操作，不会进行节点切换。一般来说，resource-stickiness的值都是正数，resource-failure-stickiness的值都是负数。另外还有一个特殊值那就是正无穷大（INFINITY）和负无穷大（-INFINITY）。如果节点的分数为负分，那么不管什么情况发生，该节点都不会接管资源（冷备节点）。随着资源的各种状态的发生，在各节点上面的分数就会发生变化，随着分数的变化，一旦某节点的分数大于当前运行该资源的节点的分数之后，heartbeat就会做出切换动作，现在运行该资源的节点将释放资源，分数高出的节点将接管该资源。 <p>在CIB的配置中，可以给每个资源定义一个分数，通过resource-stickiness来设置，同样也可以设置一个失败后丢失的分数，通过resource-failure-stickiness来设置。如下： <p>&lt;primitive id=”mysql_db” class=”ocf” type=”mysql” provider=”heartbeat”&gt; <p>&lt;meta_attributes id=”mysql_db_meta_attr”&gt;<br>&lt;attributes&gt;<br>&lt;nvpair name=”resource_stickiness” id=”mysql_db_meta_attr_1″ value=”100″/&gt;<br>&lt;nvpair name=”resource_failure_stickiness” id=”mysql_db_meta_attr_2″ value=”-100″/&gt;<br>&lt;/attributes&gt;<br>&lt;/meta_attributes&gt; <p>… <p>&lt;primitive /&gt; <p>上面的配置就是给mysql_db这个resource配置了两个分数，成功运行的时候所得到的分数（resource_stickiness）和运行失败会丢失的分数（resource_failure_stickiness），两项分数值一样多，成功则得100分，失败则-100分。 <p>除了可以通过给每个资源单独设置两项的分数之外，也可以将所有的resource设置成相同的分数，如下： <p>&lt;configuration&gt;<br>&lt;crm_config&gt;<br>&lt;cluster_property_set id=”cib-bootstrap-options”&gt;<br>&lt;attributes&gt;<br>… <p>&lt;nvpair id=”default-resource-failure-stickiness” name=”default-resource-failure-stickiness” value=”-100″/&gt;<br>&lt;nvpair id=”default-resource-stickiness” name=”default-resource-stickiness” value=”100″/&gt;<br>… <p>&lt;/attributes&gt;<br>&lt;/cluster_property_set&gt;<br>&lt;/crm_config&gt; <p>… <p>在这个配置中，就是给所有资源设置了两个默认的分数，省去单独每个资源都设置的麻烦。当然，如果在设置了这个default分数之后，同时也给部分或者全部资源也设置了这两个分数的话，将取单独设置的各个资源设置的分数而不取默认分数。 <p>除了资源的分数之外，节点自身同样也有分数。节点分数可以如下设置： <p>… <p>&lt;constraints&gt;<br>&lt;rsc_location id=”rsc_location_group_mysql” rsc=”group_mysql”&gt;<br>&lt;rule id=”mysql1_group_mysql” score=”200″&gt;<br>&lt;expression id=”mysql1_group_mysql_expr” attribute=”#uname” operation=”eq” value=”mysql1″/&gt;<br>&lt;/rule&gt;<br>&lt;rule id=”mysql2_group_mysql” score=”150″&gt;<br>&lt;expression id=”mysql2_group_mysql_expr” attribute=”#uname” operation=”eq” value=”mysql2″/&gt;<br>&lt;/rule&gt;<br>&lt;/rsc_location&gt;<br>&lt;/constraints&gt;<br>… <p>注意这里节点分数的设置是放在configuration配置项里面的constraints配置项下的，通过rule来设置。这里是通过节点主机名来匹配的（实际上heartbeat的很多配置中对主机名都是很敏感的）。这里的value值就是节点的主机名，rule里面的score就是一个节点的分数。 <p>通过上面的配置，我们可以作出如下计算： <p>a、在最开始，两边同时启动heartbeat的话，两边都没有开始运行这个resource，resource本身没有分数，那么仅仅计算节点的分数： <p>mysql1的分数：node+resource+failcount*failure=200+0+(0*(-100))=200 <p>mysql2的分数：node+resource+failcount*failure=150+0+(0*(-100))=150 <p>heartbeat会做出选择在mysql1上面运行mysql_db这个资源，然后mysql1的分数发生变化了，因为有资源自身的分数加入了： <p>mysql1的分数：node+resource+failcount*failure=200+100+(0*(-100))=300 <p>mysql2的分数：node+resource+failcount*failure=150+0+(0*(-100))=150 <p>b、过了一段时间，heartbeat的monitor发现mysql_db这个资源crash（或者其他问题）了，分数马上会发生变化，如下： <p>mysql1的分数：node+resource+failcount*failure=200+100+(1*(-100))=200 <p>mysql2的分数：node+resource+failcount*failure=150+0+(0*(-100))=150 <p>heartbeat发现mysql1节点的分数还是比mysql2的高，那么资源不发生迁移，将执行restart类操作。 <p>c、继续运行一段时间发现又有问题（或者是b后面restart没有起来）了，分数又发生变化了： <p>mysql1的分数：node+resource+failcount*failure=200+100+(2*(-100))=100 <p>mysql2的分数：node+resource+failcount*failure=150+0+(0*(-100))=150 <p>这时候heartbeat发现mysql2节点比mysql1节点的分数高了，资源将发生迁移切换，mysql1释mysql_db相关资源，mysql2接管相关资源，并在mysql2上运行mysql_db这个资源。这时候，节点的分数又会发生变化如下： <p>mysql1的分数：node+resource+failcount*failure=200+0+(2*(-100))=0 <p>mysql2的分数：node+resource+failcount*failure=150+100+(0*(-100))=250 <p>这时候如果在mysql2上面三次出现问题，那么mysql2的分数将变成-50，又比mysql1少了，资源将迁移回mysql1，mysql1的分数将变成100，而mysql2的分数将变成-150，因为又少了资源所有者的那100分。到这里，mysql2节点的分数已经是负数了。heartbeat还有一个规则，就是资源永远都不会迁移到一个分数分数是负数的节点上面去。也就是说从这以后，mysql1节点上面不管mysql_db这个资源失败多少次，不管这个资源出现什么问题，都不会迁移回mysql2节点了。一个节点的分数会在该节点的heartbeat重启之后被重置为初始状态。或者通过相关命令来对集群中某个节点的某个资源或者资源组来重置或者查看其failcount，如下： <p>crm_failcount -G -U mysql1 -r mysql_db&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #将查看mysql1节点上面的mysql_db这个资源的failcount <p>crm_failcount -D -U mysql1 -r mysql_db&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #将重置mysql1节点上面的mysql_db这个资源的failcount <p>当然，在实际应用中，我们一般都是将某一些互相关联的资源放到一起组成一个资源组，一旦资源组中某资源有问题的时候，需要迁移整个资源组的资源。这个和上面针对单个资源的情况实际上没有太多区别，只需要将上面mysql_db的设置换到资源组即可，如下： <p>… <p>&lt;group id=”group-mysql”&gt;<br>&lt;meta_attributes id=”group-mysql_meta_attr”&gt;<br>&lt;attributes&gt;<br>&lt;nvpair id=”group-mysql_meta_attr-1″ name=”resource_stickiness” value=”100″/&gt;<br>&lt;nvpair id=”group-mysql_meta_attr-1″ name=”resource_failure_stickiness” value=”-100″/&gt;<br>&lt;/attributes&gt;<br>&lt;/meta_attributes&gt;<br>&lt;primitive&gt;<br>…<br>&lt;/primitive&gt;<br>…<br>&lt;/group&gt; <p>… <p>这样，在该资源组中任何一个资源出现问题之后，都会被认为该资源组有问题，当分数低于其他节点出现切换的时候就是整个资源组的切换。 <p>另外，对于INFINITY和-INFINITY这两个值，实际上主要用途就是为了控制永远不切换和只要失败必须切换用的。因为代表的意思就是拥有正无穷大的分数和失败就到负无穷大，主要用来满足极端规则的简单配置项。 <p>总的来说，一项资源（或者资源组）在一个节点运行迁移到另一个节点之前，可以失败的次数的计算公式可以如下表示： <p>(nodeA score - nodeB score + stickiness)/abs(failure stickiness)，即为A节点分数减去B节点分数，再加上资源运行分数后得到的总分数，除以资源失败分数的绝对值。]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/253.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=253</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=253&amp;key=812b1b93</trackback:ping></item><item><title>Heartbeat V2 模块分析</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/252.html</link><pubDate>Wed, 03 Dec 2008 15:59:15 +0800</pubDate><guid>http://blog.bigcomic.com/post/252.html</guid><description><![CDATA[<p>一、heartbeat模块： <p>&nbsp;&nbsp;&nbsp; 整个Heartbeat软件的通信模块，各个节点之间的任何通信都是通过这个模块完成。这个模块会根据不同类型的通信启动不同的事件handler，当监听到不同类型的通信请求后会分给不同的handler来处理。这个从整个Heartbeat的启动日志中看出来。 <p>二、CRM：cluster resource manager <p>&nbsp;&nbsp;&nbsp; 从这个名字就可以看出这个模块基本上就是v2的heartbeat的一个只会中心，整个系统的一个大脑了，他主要负责整个系统的各种资源的当前配置信息，以及各个资源的调度。也就是根据各资源的配置信息，以及当前的运行状况来决定每一个资源（或者资源组）到底该在哪个节点运行。不过这些事情并不是他直接去做的，而是通过调度其他的一些模块来进行。 <p>&nbsp;&nbsp;&nbsp; 他通过heartbeat模块来进行节点之间的通信，调度节点之间的工作协调。随时将通过heartbeat模块收集到的各个成员节点的基本信息转交给CCM某块来更新整个集群的membership信息。他指挥LRM（local resource manager）对当前节点的各资源执行各种相应的操作（如start、stop、restart和monitor等等），同时也接收LRM在进行各种操作的反馈信息并作出相应的决策再指挥后续工作。另外CRM模块还负责将各个模块反馈回来的各种信息通过调用设定的日志记录程序记录到日志文件中。 <p>三、LRM：local resource manager <p>&nbsp;&nbsp;&nbsp; LRM是整个Heartbeat系统中直接操作所管理的各个资源的一个模块，负责对资源的监控，启动，停止或者重启等操作。这个模块目前好像支持有四种类型的资源代理（resource agent）：heartbeat自身的，ocf（open cluster framework），lsb（linux standard base，其实就是linux下标准的init脚本），还有一种就是stonith。stonith这种我还不是太清楚是一个什么类型的。 <p>&nbsp;&nbsp;&nbsp; 四种类型的resource agent中的前三种所调用的脚本分别存如下路径： <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; heartbeat：/etc/ha.d/resource.d/ <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ocf:/usr/lib/resource.d/heartbeat/ <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lsb:/etc/init.d/ <p>&nbsp;&nbsp;&nbsp; LRM就是通过调用以上路径下面的各种脚本来实现对资源的各种操作。每一种类型的脚本都可以由用户自定义，只要支持各类型的标准即可。实际上这里的标准就是接受一个标准的调用命令和参数格式，同时返回符合标准的值即可。至于脚本中的各种操作时如何的LRM并不care。 <p>四、PE：CRM Policy Engine <p>&nbsp;&nbsp;&nbsp; 他主要负责将CRM发过来的一些信息按照配置文件中的各种设置来进行计算，分析。然后将结果信息按照某种固定的格式通过CRM提交给TE（Transition engine）去分析出后续需要采取的相应的action。PE需要计算分析的信息主要是当前有哪些节点，各节点的状况，当前管理有哪些资源，各资源当前在哪一个节点，在各个节点的状态如何等等。 <p>五、TE：Transition engine <p>&nbsp;&nbsp;&nbsp; 主要工作是分析PE的计算结果，然后根据配置信息转换成后续所需的相应操作。个人感觉PE和TE组合成一个类似于规则引擎实现的功能，而且PE和TE这两个模块只有在处于active的节点被启动。另外PE和TE并不直接通信，而都是通过Heartbeat的指挥中心CRM来传达信息的。 <p>六、CIB：cluster information base <p>&nbsp;&nbsp;&nbsp; CIB在系统中充当的是当前集群中各资源原始配置以及之后动态变化了的状态，统计信息收集分发中心，是一个不断更新的信息库。当他收集到任何资源的变化，以及节点统计信息的变化后，都会集成整合到一起组成当前集群最新的信息，并分发到集群各个节点。分发动作并不是自己和各个节点通信，同样也是通过heartbeat模块来做的。 <p>&nbsp;&nbsp;&nbsp; CIB收集整理并汇总出来的信息是以一个xml格式保存起来的。实际上Heartbeat v2的资源配置文件也就是从haresources迁移到了一个叫cib.xml文件里面。该文件实际上就是CIB的信息库文件。在运行过程中，CIB可能会常读取并修改该文件的内容，以保证信息的更新。 <p>七、CCM：consensus cluster membership <p>&nbsp;&nbsp;&nbsp; CCM的最主要工作就是管理集群中各个节点的成员以及各成员之间的关系。他让集群中各个节点有效的组织称一个整体，保持着稳定的连接。heartbeat模块所担当的只是一个通信工具，而CCM是通过这个通信工具来将各个成员连接到一起成为一个整体。 <p>八、LOGD：logging daemon（non-blocking） <p>&nbsp;&nbsp;&nbsp; 一个无阻塞的日志记录程序，主要负责接收CRM从各个其他模块所收集的相关信息，然后记录到指定额度日志文件中。当logd接收到日志信息后会立刻返回给CRM反馈。并不是一定要等到将所有信息记录到文件后再返回，日志信息的记录实际上是一个异步的操作。 <p>九、APPHBD：application heartbeat daemon <p>&nbsp;&nbsp;&nbsp; apphbd模块实际上是给各个模块中可能需要用到的计时用的服务，是通过watchdog来实现的。这个模块具体的细节我还不是太清楚。 <p>十、RMD：recovery manager daemon <p>&nbsp;&nbsp;&nbsp; 主要功能是进程恢复管理，接受从apphbd所通知的某个（或者某些）进程异常退出或者失败或者hang住后的恢复请求。RMD在接受到请求后会作出restart（如果需要可能会有kill）操作。</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/252.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=252</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=252&amp;key=86bf6ad8</trackback:ping></item><item><title>MySQL Master-Slave架构下使用MMM的必要性</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/248.html</link><pubDate>Tue, 02 Dec 2008 20:39:15 +0800</pubDate><guid>http://blog.bigcomic.com/post/248.html</guid><description><![CDATA[<p>来源:<a title="http://www.muduo.net/batch.viewlink.php?itemid=311439" href="http://www.muduo.net/batch.viewlink.php?itemid=311439">http://www.muduo.net/batch.viewlink.php?itemid=311439</a>&nbsp;</p> <p>MySQL本身没有提供replication failover的解决方案(见<a href="http://dev.mysql.com/doc/refman/5.1/en/replication-faq.html#qandaitem-15-3-4-9">How can I use replication to provide redundancy or high availability?</a>) </p> <p><br>如何使Replication方案具有HA？ 答案是<a href="http://blog.kovyrin.net/mysql-master-master-replication-manager/">MMM(MySQL Master-Master Replication Manager) </a></p> <p><br><strong>MMM对MySQL Master-Slave Replication绝对是一个很有益的补充!</strong></p><strong></strong> <p><br><strong>引言</strong><br>Master-Slave的数据库机构解决了很多问题，特别是read/write比较高的web2.0应用： <br>1、写操作全部在Master结点执行，并由Slave数据库结点定时(默认60s)读取Master的bin-log <br>2、将众多的用户读请求分散到更多的数据库节点，从而减轻了单点的压力 <br>这是对Replication的最基本陈述，这种模式的在系统Scale-out方案中很有引力(如有必要，数据可以先进行Sharding，再使用replication)。 </p> <p><br>它的缺点是： <br>1、Slave实时性的保障，对于实时性很高的场合可能需要做一些处理 <br>2、高可用性问题，Master就是那个致命点(<a href="http://en.wikipedia.org/wiki/Single_point_of_failure ">SPOF:Single point of failure</a>) </p> <p><br>本文主要讨论的是如何解决第2个缺点。 </p> <p><br>DB的设计对大规模、高负载的系统是极其重要的。高可用性(<a href="http://en.wikipedia.org/wiki/High_availability ">High availability</a>)在重要的系统(critical System)是需要架构师事先考虑的。存在<a href="http://en.wikipedia.org/wiki/Single_point_of_failure ">SPOF:Single point of failure</a>的设计在重要系统中是危险的。 <br></p><strong></strong> <p><strong>Master-Master Replication</strong><br>1、使用两个MySQL数据库db01,db02，互为Master和Slave，即：一边db01作为db02的master，一旦有数据写向db01时，db02定时从db01更新 另一边db02也作为db01的master，一旦有数据写向db02时，db01也定时从db02获得更新 (这不会导致循环，MySQL Slave默认不会记录Master同步过来的变化)</p> <p><br>2、但从AppServer的角度来说，同时只有一个结点db01扮演Master，另外一个结点db02扮演Slave，不能同时两个结点扮演Master。即AppSever总是把write操作分配某个数据库(db01)，除非db01 failed，被切换。 </p> <p><br>3、如果扮演Slave的数据库结点db02 Failed了： <br>&nbsp;&nbsp;&nbsp;&nbsp; a)此时appServer要能够把所有的read,write分配给db01，read操作不再指向db02 <br>&nbsp;&nbsp;&nbsp;&nbsp; b)一旦db02恢复过来后，继续充当Slave角色，并告诉AppServer可以将read分配给它了 </p> <p><br>4、如果扮演Master的数据库结点db01 Failed了 <br>&nbsp;&nbsp;&nbsp;&nbsp; a)此时appServer要能够把所有的写操作从db01切换分配给db02，也就是切换Master由db02充当 <br>&nbsp;&nbsp;&nbsp;&nbsp; b)db01恢复过来后，充当Slave的角色，Master由db02继续扮演 <br></p> <p>难点： <br>3、4要如何自动进行？<br><strong></strong></p> <p><strong>Master-Master with n Slaves Replication</strong><br><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="436" alt="redundancy-after" src="http://blog.bigcomic.com/upload/MySQLMasterSlaveMMM_1227F/redundancyafter.png" width="542" border="0"> </p> <p><br>这比上一个还要复杂，即：当一个Master Fail时，所有的Slave不再从原来失败的那个Master(db01)获取更新日志，而应该“自动”切换到最新充当Master角色的数据库db02。 </p> <p><br><strong>MMM，a greate project!</strong></p><strong></strong> <p>MMM的基本信息请参考它的网站(见后"参考资料") <br>MMM有3个重要的器件: <br>1、mmmd_mon - monitoring script which does all monitoring work and makes all decisions about roles moving and so on. </p> <p>2、mmmd_agent - remote servers management agent script, which provides monitoring node with simple set of remote services to make servers management easier, more flexible abd highly portable. <br>3、mmm_control - simple script dedicated to management of the mmmd_mon processes by commands. <br></p> <p>每一个MySQL服务器器结点需要运行mmmd_agent，同时在另外的一个机器上(可以是独立的一台机器，也可以是和AppServer共享同一个服务器)运行mmmd_mon。形成1 * mmmd_mon + n * mmmd_agent的部署架构。 <br></p> <p>MMM利用了虚拟IP的技术：1个网卡可以同时使用多个IP。(所以使用MMM时，需要2*n+1个IP，n为mysql数据库结点个数，包括master,slave) <br></p> <p>当有数据库结点fail时，mmmd_mon检测不到mmmd_agent的心跳或者对应的MySQL服务器的状态，mmmd_mon将进行决定，并下指令给某个正常的数据库结点的mmmd_agent，使得该mmmd_agent“篡位”<em>使用(注)</em>刚才fail的那个结点的虚拟IP，使得虚拟IP实际从指向fail的那个机器自动转为此时的这个正常机器。 </p> <p><br>注：据Qieqie猜测是将获得的虚拟IP设置给网卡，也只能这样了，改天测试验证一下。</p> <p>repeat: <a href="http://blog.kovyrin.net/mysql-master-master-replication-manager/">MMM</a>对MySQL Master-Slave Replication绝对是一个很有益的补充! </p> <p><strong></strong>&nbsp;</p> <p><strong>参考资料</strong><br>Switching Masters During Failover <br><a href="http://dev.mysql.com/doc/refman/5.1/en/replication-solutions-switch.html">http://dev.mysql.com/doc/refman/5.1/en/replication-solutions-switch.html</a><br>downpour: 讨论一下基于Master-Slave数据库模式的J2EE开发的框架选择 <br><a href="http://www.javaeye.com/topic/143714">http://www.javaeye.com/topic/143714</a><br>MMM <a href="http://blog.kovyrin.net/mysql-master-master-replication-manager/">http://blog.kovyrin.net/mysql-master-master-replication-manager/</a><br>Project page on Google Code: <a href="http://code.google.com/p/mysql-master-master">http://code.google.com/p/mysql-master-master</a><br>mmm-devel users group: <a href="http://groups.google.com/group/mmm-devel">http://groups.google.com/group/mmm-devel</a></p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/248.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=248</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=248&amp;key=22558a27</trackback:ping></item><item><title>mysql压力测试工具：mysqlslap</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/254.html</link><pubDate>Mon, 01 Dec 2008 16:01:15 +0800</pubDate><guid>http://blog.bigcomic.com/post/254.html</guid><description><![CDATA[<p><strong>mysqlslap是一个mysql官方提供的压力测试工具。以下是比较重要的参数：</strong><br>–defaults-file，配置文件存放位置<br>–concurrency，并发数<br>–engines，引擎<br>–iterations，迭代的实验次数<br>–socket，socket文件位置 <p><strong>自动测试：</strong><br>–auto-generate-sql，自动产生测试SQL<br>–auto-generate-sql-load-type，测试SQL的类型。类型有mixed，update，write，key，read。<br>–number-of-queries，执行的SQL总数量<br>–number-int-cols，表内int列的数量<br>–number-char-cols，表内char列的数量 <p>例如：<br>shell&gt;mysqlslap –defaults-file=/u01/mysql1/mysql/my.cnf –concurrency=50,100 –iterations=1 –number-int-cols=4 –auto-generate-sql –auto-generate-sql-load-type=write –engine=myisam –number-of-queries=200 -S/tmp/mysql1.sock<br>Benchmark<br>Running for engine myisam<br>Average number of seconds to run all queries: 0.016 seconds<br>Minimum number of seconds to run all queries: 0.016 seconds<br>Maximum number of seconds to run all queries: 0.016 seconds<br>Number of clients running queries: 50<br>Average number of queries per client: 4 <p>Benchmark<br>Running for engine myisam<br>Average number of seconds to run all queries: 0.265 seconds<br>Minimum number of seconds to run all queries: 0.265 seconds<br>Maximum number of seconds to run all queries: 0.265 seconds<br>Number of clients running queries: 100<br>Average number of queries per client: 2 <p><strong>指定数据库的测试：</strong><br>–create-schema，指定数据库名称<br>–query，指定SQL语句，可以定位到某个包含SQL的文件 <p>例如：<br>shell&gt;mysqlslap –defaults-file=/u01/mysql1/mysql/my.cnf –concurrency=25,50 –iterations=1 –create-schema=test –query=/u01/test.sql -S/tmp/mysql1.sock<br>Benchmark<br>Average number of seconds to run all queries: 0.018 seconds<br>Minimum number of seconds to run all queries: 0.018 seconds<br>Maximum number of seconds to run all queries: 0.018 seconds<br>Number of clients running queries: 25<br>Average number of queries per client: 1 <p>Benchmark<br>Average number of seconds to run all queries: 0.011 seconds<br>Minimum number of seconds to run all queries: 0.011 seconds<br>Maximum number of seconds to run all queries: 0.011 seconds<br>Number of clients running queries: 50<br>Average number of queries per client: 1</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/254.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=254</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=254&amp;key=e53d0df6</trackback:ping></item><item><title>使用TC4400自带蓝牙连接简报鲨8000</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/246.html</link><pubDate>Mon, 17 Nov 2008 16:38:08 +0800</pubDate><guid>http://blog.bigcomic.com/post/246.html</guid><description><![CDATA[<p>一、在设备管理器中查看鼠标的设备ID号.</p><p><strong>HID\{00001124-0000-1000-8000-00805f9b34fb}&amp;VID_045E&amp;PID_0701&amp;Col02</strong></p><p>上面的字符就是简报鲨鱼8000的设备ID</p><p><a href="http://blog.bigcomic.com/upload/TC44008000_E669/image.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="199" alt="image" width="414" border="0" src="http://blog.bigcomic.com/upload/TC44008000_E669/image_thumb.png" /></a></p><p>&nbsp;</p><p>二、修改驱动</p><p>我安装的是IntelliPoint 6.3， 其他版本的驱动文件名称或路径可能不同。</p><p><strong>C:\Program Files\Microsoft IntelliPoint\pnt32uw.inf</strong></p><p>搜索</p><p>HID\{00001124-0000-1000-8000-00805f9b34fb}_VID&amp;0002045e_PID&amp;0701&amp;Col02</p><p>改为</p><p>HID\{00001124-0000-1000-8000-00805f9b34fb}&amp;VID_045E&amp;PID_0701&amp;Col02</p><p>一共有三处，修改之前注意备份.</p><p>&nbsp;</p><p>三、更新驱动</p><p>一定要从列表或指定位置安装，不要自动搜索。</p><p>&nbsp;</p><p>四、重新启动</p><p>&nbsp;</p><p>EOF</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/246.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=246</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=246&amp;key=5c941239</trackback:ping></item><item><title>ubuntu 7.10 vsftp的虚拟用户设置</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/241.html</link><pubDate>Thu, 06 Nov 2008 01:04:42 +0800</pubDate><guid>http://blog.bigcomic.com/post/241.html</guid><description><![CDATA[第一步: 配置PAM  <table class="term" cellspacing="0" cellpadding="2" width="609" border="0"> <tbody> <tr> <td class="term" valign="top" width="607">[root@www linux]# vi /etc/pam.d/vsftpd<br><span class="text_command"><br>#%PAM-1.0<br>session optional pam_keyinit.so force revoke<br>auth required /lib/security/pam_userdb.so db=/etc/vsftpd/vsftpd_users<br>account required /lib/security/pam_userdb.so db=/etc/vsftpd/vsftpd_users<br>#auth required pam_listfile.so item=user sense=deny file=/etc/vsftpd/ftpusers onerr=succeed<br>#auth required pam_shells.so<br>#auth include system-auth<br>#account include system-auth<br>#session include system-auth<br>#session required pam_loginuid.so</span></td></tr></tbody></table> <p>&nbsp; <p>第二步: 建立vsftp的本地帐户</p> <table class="term" cellspacing="0" cellpadding="2" width="609" border="0"> <tbody> <tr> <td class="term" valign="top" width="607"> <p>[root@www linux]# adduser -d /home/ftp/ pencat</p></td></tr></tbody></table> <p>&nbsp;</p> <p>第三步: 配置vsftp</p> <table class="term" cellspacing="0" cellpadding="2" width="609" border="0"> <tbody> <tr> <td class="term" valign="top" width="607"> <p>[root@www linux]# vim /etc/vsftpd.conf  <p>local_enable=YES<br>write_enable=YES<br>local_umask=022<br>dirmessage_enable=YES<br>xferlog_enable=YES<br>connect_from_port_20=YES<br>xferlog_file=/var/log/vsftpd.log<br>xferlog_std_format=YES<br>chroot_local_user=YES<br>listen=YES<br>pam_service_name=vsftpd<br>userlist_enable=YES<br>user_sub_token=$USER<br>local_root=/home/ftp/$USER<br>guest_enable=YES<br>guest_username=pencat<br>anon_umask=0022<br>anon_upload_enable=YES<br>anon_mkdir_write_enable=YES<br>anon_other_write_enable=YES<br>anonymous_enable=NO</p></td></tr></tbody></table> <p>&nbsp;</p> <p>第四步: 建立虚拟用户</p> <table class="term" cellspacing="0" cellpadding="2" width="608" border="0"> <tbody> <tr> <td class="term" valign="top" width="606"> <p>[root@www linux]# vim <span class="text_command">/etc/vsftpd/vsftpd_users.txt</span></p> <p><span class="text_command">username<br>password<br>pencat<br>password for pencat</span></p> <p>[root@www linux]# db3_load -T -t hash -f <span class="text_command">/etc/vsftpd/vsftpd_users.txt </span><span class="text_command">/etc/vsftpd/vsftpd_users.db</span></p> <p>[root@www linux]# chmod 600 /etc/vsftpd/vsftpd_users.db /etc/vsftpd/vsftpd_users.txt</p></td></tr></tbody></table> <p>这里需要注意ubuntu 7.10下需要用db3_load, 否则验证是会失败的.</p> <p>&nbsp;</p> <p>第五步: 建立虚拟用户的目录,以及设置权限</p> <table class="term" cellspacing="0" cellpadding="2" width="609" border="0"> <tbody> <tr> <td class="term" valign="top" width="607"> <p>[root@www linux]# mkdir -p /home/ftp/username<br><br>[root@www linux]# mkdir -p /home/ftp/pencat<br><br>[root@www linux]# chwon -R pencat.pencat /home/ftp</p></td></tr></tbody></table> <p><br>第六步: 完成并测试</p> <table class="term" cellspacing="0" cellpadding="2" width="609" border="0"> <tbody> <tr> <td class="term" valign="top" width="607"> <p>[root@www linux]# tail -f /var/log/auth.log</p> <p>Mar 2 15:14:51 www vsftpd: pam_userdb(vsftpd:auth): user 'pencat' granted access</p></td></tr></tbody></table> <p>&nbsp;</p> <p>[EOF]</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/241.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=241</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=241&amp;key=3c5645d7</trackback:ping></item><item><title>centos 5.2 配置pptp客户端</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/239.html</link><pubDate>Mon, 01 Sep 2008 01:27:28 +0800</pubDate><guid>http://blog.bigcomic.com/post/239.html</guid><description><![CDATA[<p>1. 下载源码包</p><p># wget http://nchc.dl.sourceforge.net/sourceforge/pptpclient/pptp-1.7.2.tar.gz</p><p>2. 编译</p><p># make</p><p>3. 安装</p><p># make install</p><p>4. 配置</p><p># pptpsetup --create tunnelname --server xxx.xxx.xxx.xxx --username somebody --password sercet</p><p>5. 连接</p><p># pppd call tunnelname</p><p>6. 断开</p><p># killall pppd</p><p>注意事项：</p><p>在处理路由的时候采用client to lan方式，需要增加对方lan的路由或者目标网络的路由. </p><p># route add -net 192.168.2.0 netmask 255.255.255.0 dev ppp0</p><p>ppp0是pptp连接的名字， 如果不确定 可以使用ifconfig命令查看</p><p>&nbsp;</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/239.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=239</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=239&amp;key=8562c7b6</trackback:ping></item><item><title>MySQL可靠性方案分析与比较</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/236.html</link><pubDate>Wed, 07 May 2008 16:26:53 +0800</pubDate><guid>http://blog.bigcomic.com/post/236.html</guid><description><![CDATA[<p>从基本情况、成本、优缺点和应用场合等方面对5种MySQL的可靠性方案进行了分析和比较，对MySQL的开发和管理有一定的借鉴作用。</p><p><strong>1．MySQL Clustering(ndb-cluster stogare) </strong></p><p>简介：<br />MySQL公司以存储引擎方式提供的高可靠性方案，是事务安全的，实时复制数据，可用于需要高可靠性及负载均衡的场合。该方案至少需要三个节点服务器才能达到较好的效果。<br /><br />成本：<br />节点服务器对RAM的需求很大，与数据库大小呈线性比例； <br />最好使用千兆以太网络； <br />还需要使用Dolphin公司提供的昂贵的SCI卡。<br /><br />优点：<br />可用于负载均衡场合； <br />可用于高可靠性场合； <br />高伸缩性； <br />真正的数据库冗余； <br />容易维护。<br /><br />缺点：<br />随着数据库的变大，对RAM的需求变得更大，因此成本很高； <a name="entrymore"></a><br /><br />速度：<br />几乎 比典型的单独服务器（无千兆以太网，无SCI卡，存储引擎相关的限制少）慢10倍。<br /><br />应用场合：<br />冗余，高可靠性，负载均衡<br />&nbsp;</p><p><strong>2. MySQL / GFS-GNBD/ HA (Active/Passive)</strong></p><p>简介：<br />如果多个MySQL服务器使用共享硬盘作为数据存储，此方案如何？<br /><br />GFS/GNBD可以提供所需的共享硬盘。<br /><br />GFS是事务安全的文件系统。同一时刻你可以让一个MySQL使用共享数据。<br /><br />成本：<br />最多n台高性能服务器的成本，其中一个激活的，其他作为备份服务器。<br /><br />优点：<br />高可靠性 <br />某种程度的冗余 <br />按照高可靠性进行伸缩<br /><br />缺点：<br />没有负载均衡 <br />没有保证的冗余 <br />无法对写操作进行伸缩<br /><br />速度:<br />单独服务器的2倍。对读操作支持得较好。<br /><br />应用场合<br /><br />需要高可靠性的、读操作密集型的应用<br />&nbsp;</p><p><strong>3. MySQL / DRBD / HA (Active/Passive) </strong><br />&nbsp;</p><p>简介：<br />如果多个MySQL服务器使用共享硬盘作为数据存储，此方案如何？<br /><br />DRBD可以提供这样的共享硬盘。DRBD可以被设置成事务安全的。<br /><br />同一时刻你可以让一个MySQL使用共享数据。<br /><br />成本：<br />最多n台高性能服务器的成本，其中一个激活的，而其他则作为备份服务器。<br /><br />优点：<br />高可靠性； <br />一定程度的冗余； <br />以高可靠性名义来看是可伸缩的。<br /><br />缺点：<br />没有负载均衡 <br />没有保证的冗余 <br />在写负载方面没有伸缩性<br /><br />速度：<br />在读写方面相当于单独服务器<br /><br />应用场合<br /><br />需要高可靠性、读操作密集型的应用</p><p><strong>4. MySQL Write Master / Multiple MySQL Read Slaves (Active/Active)</strong> 简介：<br />考虑不同的读、写DB数据库连接的情况。可以使用一台主服务器用于写操作，而采用n台从服务器用于读操作。<br /><br />成本：<br />最多1台高性能写服务器，n台读服务器的成本<br /><br />优点：<br />读操作的高可靠性； <br />读操作的负载均衡； <br />在读操作负载均衡方面是可伸缩的。<br />缺点：<br />无写操作的高可靠性； <br />无写操作的负载均衡； <br />在写操作方面无伸缩性；<br /><br />速度：<br />同单独服务器；在读操作方面支持得较好<br /><br />应用场合<br /><br />读操作密集型的、需要高可靠性和负载均衡的应用。<br />&nbsp;</p><p><strong>5. Standalone MySQL Servers(Functionally separated) (Active)</strong></p><p>多台功能分离的单独服务器，没有高可靠性、负载均衡能力，明显缺点太多，不予考虑。<br /><br />总结： <br />MySQL官方网站推荐的HA方案是结合DRBD (本文的方案3) 和 Replication (方案4)。如果再加上Linux Heartbeat还可实现Auto-failover功能，这样down机时间会大大减少。<br />&nbsp;</p><p>&nbsp;</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/236.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=236</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=236&amp;key=c7e5ba0f</trackback:ping></item><item><title>vbs的xmlHttp实用程序的经典函数</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/235.html</link><pubDate>Fri, 25 Apr 2008 09:16:36 +0800</pubDate><guid>http://blog.bigcomic.com/post/235.html</guid><description><![CDATA[<p><font face="Courier New">Set xmlHttp = CreateObject(&quot;microsoft.xmlhttp&quot;)<br />Set oShell = CreateObject(&quot;WScript.Shell&quot;)<br />sCurrDir = oShell.CurrentDirectory</font></p><p>&nbsp;</p><p><br /><font face="Courier New">Function GetPage(Method,Url,Async,PostContent,FileName)<br />xmlHttp.open Method,Url,Async<br />If Method = &quot;POST&quot; Then<br />&nbsp;&nbsp; xmlhttp.setRequestHeader &quot;Content-Type&quot;,&quot;application/x-www-form-urlencoded&quot;<br />&nbsp;&nbsp; xmlhttp.setRequestHeader &quot;Content-Length&quot;,Len(PostContent)<br />End If<br />xmlHttp.send(PostContent)<br />If Async = False Then GetPage = BytesToBstr(xmlHttp.responseBody,&quot;GB2312&quot;,FileName) Else GetPage = &quot;&quot;<br />End Function</font></p><p><font face="Courier New">Function BytesToBstr(body,Cset,FileName)<br />Set objstream = CreateObject(&quot;ADODB.Stream&quot;)<br />with objstream<br />.Type = 1<br />.Mode =3<br />.Open<br />.Write body<br />If not trim(FileName)=&quot;&quot; Then .SaveToFile LCase(FileName),2<br />.Position = 0<br />.Type = 2<br />.Charset = Cset<br />End With <br />BytesToBstr = objstream.ReadText<br />objstream.Close<br />End Function</font></p><p><font face="Courier New"><p><br />&nbsp;</p><p>使用方法：</p><p>GetPage(<em>提交方法</em>, <em>提交URL</em>, <em>是否异步</em>, <em>POST内容</em>, [<em>另存为文件名</em>])</p><p>几乎封装了一切可用的，呵呵。以后用xmlHttp做刷网页，破密码等，都是很简单的调用了。效率很高，直接继承了IE的Cookie。</p></font></p><p>&nbsp;</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/235.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=235</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=235&amp;key=03156c85</trackback:ping></item><item><title>VB6的编译预处理</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/233.html</link><pubDate>Wed, 09 Apr 2008 13:03:13 +0800</pubDate><guid>http://blog.bigcomic.com/post/233.html</guid><description><![CDATA[<p>用关键字&#8220;#&#8221;来实现条件编译，下面用一个实际例子（调试版本）来说明：   <br /></p>  <p>在声明部分用#Const声明一个常量。</p>  <p>#Const DebugVer = True</p>  <p>代码中这样写：</p>  <p>#If DebugVer = True Then    <br /> Msgbox &quot;This is the Debug Version Please Report any Messages&quot;     <br />#End If </p>  <p>那么任何位于 #IF&#8230; #End IF之间的代码将被编译到最终的EXE文件中，因为你上边定义的条件常量DebugVer的值为true。 如果将DebugVer的值改为false，那么编译工程时将不会编译包含在#IF&#8230; #End IF之间的代码。这里的条件常量不一定非要是布尔类型的常量，可以象使用其他常量一样使用这个常量，但是注意它是常量，每次运行它只能是一个值。</p>  <p>在举个例子，根据不同操作系统，需要不用的编译结果（注意是根据操作系统不同而编译结果不同，并不是根据不同的操作系统运行不同的代码。）   <br />声明： </p>  <p>#Const OSVer= &quot;WIN95&quot; '(or WIN98 or WINXP)</p>  <p>代码中： </p>  <p>#If OSVer = &quot;WIN95&quot; Then    <br /> 'WIN95 Code here     <br />#ElseIf OSVer = &quot;WIN98&quot; Then     <br /> 'WIN98 Code here     <br />#ElseIF OSVer = &quot;WINXP&quot; Then     <br /> 'WINXP Code here     <br />#Else     <br /> 'Non-specific OS here     <br />#End If</p>  <p>以上谈到的方法，＃Const使用的范围都是当前模块，那么有没有办法设定全局的，答案是&#8220;有&#8221;。可以进行如下操作：   <br />打开&#8220;工程&#8221;=&gt;&#8220;属性&#8221;，切换到&quot;生成&quot;选项卡，在下边你会看到文本框（条件编译参数）允许设定条件编译参数。比如上面的例子，你可以输入如下参数：    <br />&quot;OSVer=WINXP: DebugVer=True&quot;（没有引号）    <br />如果需要设置多个参数，每个参数之间用冒号分隔，这样设定后就不需要每个模块都用#Const来设置。</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/233.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=233</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=233&amp;key=afa0b6c7</trackback:ping></item><item><title>Linux内核学习笔记(1)</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/232.html</link><pubDate>Thu, 03 Apr 2008 15:31:38 +0800</pubDate><guid>http://blog.bigcomic.com/post/232.html</guid><description><![CDATA[<p>首先到<a title="http://kernel.org/pub/linux/kernel" href="http://kernel.org/pub/linux/kernel">http://kernel.org/pub/linux/kernel</a>下载一个内核源文件. 我选择了linux-2.6.24-rc8.tar.gz</p>  <table class="term" width="508"><tbody>     <tr>       <td class="term" width="506">         <p>[root@www linux]# <span class="text_command">wget http://url/linux-2.6.24-rc8.tar.gz</span>                <br />[root@www linux]# ls -l             <br />total 57756             <br />-rwxr-xr-x&#160;&#160;&#160; 1 root&#160;&#160;&#160;&#160; root&#160;&#160;&#160;&#160; 59074448 Apr&#160; 3 15:50 linux-2.6.24-rc8.tar.gz             <br />[root@www linux]# <span class="text_command">tar -zxvf linux-2.6.24-rc8.tar.gz</span>             <br />[root@www linux]# <span class="text_command">cd linux-2.6.24-rc8v             <br />[root@www linux-2.6.24-rc8]# <span class="text_command">make mrproper</span>             <br />[root@www linux-2.6.24-rc8]# <span class="text_command">make menuconfig</span>             <br />&#160; HOSTCC&#160; scripts/basic/fixdep             <br />&#160; HOSTCC&#160; scripts/basic/docproc             <br />&#160; HOSTCC&#160; scripts/kconfig/conf.o             <br />&#160; HOSTCC&#160; scripts/kconfig/kxgettext.o             <br />&#160; HOSTCC&#160; scripts/kconfig/lxdialog/checklist.o             <br />&#160; HOSTCC&#160; scripts/kconfig/lxdialog/inputbox.o             <br />&#160; HOSTCC&#160; scripts/kconfig/lxdialog/menubox.o             <br />&#160; HOSTCC&#160; scripts/kconfig/lxdialog/textbox.o             <br />&#160; HOSTCC&#160; scripts/kconfig/lxdialog/util.o             <br />&#160; HOSTCC&#160; scripts/kconfig/lxdialog/yesno.o             <br />&#160; HOSTCC&#160; scripts/kconfig/mconf.o             <br />&#160; SHIPPED scripts/kconfig/zconf.tab.c             <br />&#160; SHIPPED scripts/kconfig/lex.zconf.c             <br />&#160; SHIPPED scripts/kconfig/zconf.hash.c             <br />&#160; HOSTCC&#160; scripts/kconfig/zconf.tab.o</p>          <p>           <br /></p>       </td>     </tr>   </tbody></table>  <p>#make mrproper    <br />#make config（基于文本的最为传统的配置界面）     <br />#make menuconfig（基于文本选单的配置界面）     <br />#make xconfig（基于图形窗口模式的配置界面）     <br />#make oldconfig（在原来内核配置的基础上修改）</p>  <p>&#160;</p>  <table class="term" width="508"><tbody>     <tr>       <td class="term" width="506">         <pre>#wget </pre>      </td>    </tr>  </tbody></table>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/232.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=232</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=232&amp;key=c8b22f9f</trackback:ping></item><item><title>P2P软件引起的APACHE假死</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/230.html</link><pubDate>Wed, 02 Apr 2008 13:29:11 +0800</pubDate><guid>http://blog.bigcomic.com/post/230.html</guid><description><![CDATA[<p>环境: Apache/1.3.33    <br />症状: Apache 进程达到152个后停止响应 </p>  <p>日志2中看到很多BT软件连上来,在路由的连接日志中显示有很多BT连接. 可能是本地BT软件用了80端口, 远程BT回连的时候被NAT到了APACHE所在的服务器. 连接数过多造成HTTP服务假死. </p>  <p><a href="http://blog.bigcomic.com/upload/P2PAPACHE_BDEE/ros_apache_log_1.png" target="_blank"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="141" alt="ros_apache_log_1" src="http://blog.bigcomic.com/upload/P2PAPACHE_BDEE/ros_apache_log_1_thumb.png" width="244" border="0" /></a> </p>  <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; APACHE日志-1 </p>  <p>&#160;</p>  <p><a href="http://blog.bigcomic.com/upload/P2PAPACHE_BDEE/ros_apache_log_2.png" target="_blank"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="111" alt="ros_apache_log_2" src="http://blog.bigcomic.com/upload/P2PAPACHE_BDEE/ros_apache_log_2_thumb.png" width="244" border="0" /></a> </p>  <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; APACHE日志-2 </p>  <p>&#160;</p>  <p><a href="http://blog.bigcomic.com/upload/P2PAPACHE_BDEE/ros_apache_log_3.png" target="_blank"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="100" alt="ros_apache_log_3" src="http://blog.bigcomic.com/upload/P2PAPACHE_BDEE/ros_apache_log_3_thumb.png" width="244" border="0" /></a> </p>  <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 路由连接记录 </p>  <p>在NAT规则中抛弃含有BT字样的连接后问题解决. 这个问题应该用连接数来解决,否则遇到其他BT软件时还会出现这个问题.</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/230.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=230</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=230&amp;key=1735d378</trackback:ping></item><item><title>Mount NTFS Partitions</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/220.html</link><pubDate>Mon, 31 Mar 2008 14:40:00 +0800</pubDate><guid>http://blog.bigcomic.com/post/220.html</guid><description><![CDATA[<p>Windows uses a different filesystem (NTFS) to store files. In order for Fedora to read that filesystem, you require NTFS support in your kernel. You can either recompile your kernel for NTFS read support -OR- obtain the proper kernel module.</p>  <p><b>NOTE:</b> For users who upgraded from FC5 please first read the <a href="http://www.mjmwired.net/#problems">known bugs and problems</a>.</p>  <p>To setup NTFS access you must (1) install NTFS support, (2) check how many partitions you have, (3) create mount points, (4) mount partitions, and (5) update <tt>fstab</tt> to mount at next boot.</p>  <p><b>NOTE:</b> Previously Livna was recommended. However that solution has been known to be problematic in that it <i>may</i> update your kernel, which is normal behaviour. It is recommended to use NTFS-3G instead as it is supported in Fedora Extras and does NOT require kernel updates/upgrades. NTFS-3G also provides safe read-write access. (However SELinux may cause some problems for NTFS-3G.)</p>  <p><b>1. Install NTFS Support</b></p>  <p>For <tt>yum</tt> users:</p>  <pre># <a href="http://www.mjmwired.net/#sudo">sudo</a> yum install fuse fuse-libs ntfs-3g ntfsprogs ntfsprogs-gnomevfs</pre><br/><p>Users without yum, download <tt>fuse</tt>, <tt>fuse-lib</tt> and <tt>ntfs-3g</tt> (<tt>ntfsprogs</tt> and <tt>ntfsprogs-gnomevfs</tt> are optional) from <a href="http://download.fedora.redhat.com/pub/fedora/linux/extras/6/">Fedora Extras</a>. Save them to a separate directory (<tt>ntfs</tt>). They are less than 1MB download.</p><br/><pre># cd ntfs<br/># sudo rpm -ivh fuse* ntfs*</pre><br/><p>No kernel version checking is required, so long as you are using a FC6 kernel.</p><br/><p><b>2. Check Your Partitions</b></p><br/><p>Use <tt>fdisk</tt> to list partitions. Most ATA hard drives will be <tt>/dev/hda</tt>. Drives may also show up as <tt>/dev/hdb</tt>, <tt>/dev/sda</tt> depending on your configuration.</p><br/><pre># sudo /sbin/fdisk -lu <b>/dev/hda</b> | grep NTFS<br /></pre><br/><p>/dev/hda1 * 63 33559784 16779861 7 HPFS/NTFS<br/>  <br />/dev/hda2&#160;&#160;&#160;&#160;&#160;&#160;&#160; 33559785&#160;&#160;&#160; 67119569&#160;&#160;&#160; 16779892+&#160;&#160; 7&#160; HPFS/NTFS<br/><br/>  <br />/dev/hda3&#160;&#160;&#160;&#160;&#160;&#160;&#160; 67119570&#160;&#160; 100679354&#160;&#160;&#160; 16779892+&#160;&#160; 7&#160; HPFS/NTFS</p><br/><p>Usually the first will be a drive &quot;letter&quot;: C drive, next D, etc. Hence <tt>/dev/hda1</tt> is my C:\ drive used by Windows.</p><br/><p><b>3. Create Mount Points</b></p><br/><p>For every partition in step 2 that you wish to access, you will need a &quot;mount point&quot;. A mount point is just a directory. Common directories are: <tt>/media/</tt> and <tt>/mnt/</tt>. Use whichever, but be consistent.</p><br/><pre># cd /media/<br/># sudo mkdir c_drive d_drive e_drive</pre><br/><p>You do not have to use these names, if you prefer to create folders such as movies, documents, or winxp, any name will work (<i>without spaces</i>).</p><br/><p><b>4. Mount Partitions</b></p><br/><p>Using NTFS-3G, we can mount the NTFS partition read-write, however it is recommended for novices as read-only. The following mounts and sets the permissions so all users can read the contents of each partition.</p><br/><pre># sudo mount /dev/hda1 /media/c_drive -t ntfs-3g -r -o umask=0222<br /># sudo mount /dev/hda2 /media/d_drive -t ntfs-3g -r -o umask=0222<br /># sudo mount /dev/hda3 /media/e_drive -t ntfs-3g -r -o umask=0222</pre><br/><p><b>Read/Write Access</b>: The above is for <i>read-only</i> access. In order to mount read/write, you must use the <tt>-rw -o umask=0000</tt>. Example:</p><br/><pre># sudo mount /dev/hda1 /media/c_drive -t ntfs-3g <b>-rw -o umask=0000</b></pre><br/><p><i>HIGHLY RECOMMENDED</i>: Please run <tt>man mount</tt> to understand what <tt>umask=</tt> does.</p><br/><p><b>5. Update /etc/fstab</b></p><br/><p>Every time Fedora boots, the partitions must be mounted. To automatically mount, you must edit <tt>/etc/fstab</tt>.</p><br/><p>Open <tt>/etc/fstab</tt> in an editor: (use <tt>nano</tt> instead of <tt>gedit</tt> if you do not have a GUI)</p><br/><pre># sudo gedit /etc/fstab</pre><br/><p>Add these lines to the END of the file:</p><br/><pre>/dev/hda1   /media/c_drive     ntfs-3g    ro,defaults,umask=0222 0 0<br />/dev/hda2   /media/d_drive     ntfs-3g    ro,defaults,umask=0222 0 0<br />/dev/hda3   /media/e_drive     ntfs-3g    ro,defaults,umask=0222 0 0<br /><b>Read/Write Access</b>: The above is for <i>read-only</i> access. <br />In order to mount read/write, you must use the <tt>rw,defaults,umask=0000</tt>. Example:</pre><br/><pre>/dev/hda1   /media/c_drive     ntfs-3g    <b>rw</b>,defaults,<b>umask=0000</b> 0 0</pre><br/><p>Done!</p><br/><p><b><u>NOTE: SELinux Problems</u></b></p><br/><p>Users of SELinux will fix Fedora blocks the automounting of ntfs partitions when using NTFS-3G. This is a <a href="https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=211767">Fedora/SELinux bug</a>, not NTFS-3G. Some support can be found on the <a href="http://ntfs-3g.org/support.html#questions">NTFS-3G support page.</a>. However for now users can mount everything when they log in by running:</p><br/><pre># sudo mount -a</pre><br/><p><b><u>NOTE for FAT32 users</u></b></p><br/><p>If you have FAT32 or FAT16 partitions, instead of <tt>ntfs-3g</tt> above you can use <tt>vfat</tt> to mount your partitions. No extra modules or downloads are required, this is built into the kernel. Just replace <tt>vfat</tt> for every place we have <tt>ntfs-3g</tt> when mounting and when editting <tt>/etc/fstab</tt>.</p><br/><p>FAT32/FAT16 read <b>and</b> write is supported. If you wish to mount read/write, then use: <tt>'-rw'</tt> for Step <b>4. Mounting Partitions</b>, and <tt>'rw,defaults,umask=0000 0 0'</tt> for Step <b>5. Updating /etc/fstab</b>.</p><br/><p><b><u>NOTE for Livna NTFS Modules</u></b></p><br/><p>The Livna NTFS modules are <i>read-only access</i>. I do not recommend using them due to the kernel dependancy. If you require them or NTFS-3G will not work then first setup the <a href="http://www.mjmwired.net/#yum">Livna</a> repository. Then you can install them:</p><br/><pre># sudo yum install kmod-ntfs</pre><br/><p>For all the above changes you should use <tt>ntfs</tt> instead of <tt>ntfs-3g</tt>.</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/220.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=220</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=220&amp;key=6cd44644</trackback:ping></item><item><title>routeos设置不当造成的大附件发送超时</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/215.html</link><pubDate>Thu, 13 Mar 2008 10:47:23 +0800</pubDate><guid>http://blog.bigcomic.com/post/215.html</guid><description><![CDATA[<p>公司内部有个应用.&nbsp; 把某目录的ZIP定时发送到美国, 那边自动解析附件后再处理.&nbsp; ZIP文件通常是500K-3M不等.&nbsp; 之前一直很正常. 昨天下午负责人向我反映,发出去的信美国收不到. 经过测试,附件超过100K就发不出去.&nbsp;&nbsp; 大附件的邮件是发出去也收不进来.</p><p>环境<br />linux 2.6.9-55.0.12.ELsmp<br />postfix-2.3.6<br />routeos 2.9.27<br />3条光纤接入 10M/10M/2M<br /><br />遇到问题第一步就是抓包分析 tcpdump tcp port 25 and host 192.168.2.4 -w&nbsp;smtp&nbsp;</p><p><a target="_blank" href="http://blog.bigcomic.com/upload/emerr_1.png"><img height="432" alt="" width="600" border="0" src="http://blog.bigcomic.com/upload/emerr_1.png" /></a><br />图-1</p><p>从结果看握手很正常. 一段时间后开始丢包.&nbsp; 肯定是连接超时造成的。查了postfix日志, 果然有超时的记录。在defer pool里有很多超时的信.<br /><br />&lt;xxxxxx@yahoo.com.cn&gt;: conversation with mta-v1.mail.vip.cnb.yahoo.com[203.209.228.230] timed out while sending message body<br />recipient=xxxxxx@yahoo.com.cn<br />offset=547<br />dsn_orig_rcpt=rfc822;xxxxxx@yahoo.com.cn<br />status=4.4.2<br />action=delayed<br />reason=conversation with mta-v1.mail.vip.cnb.yahoo.com[203.209.228.230] timed out while sending message body<br /></p><p>想了一下, 可能有几种情况.</p><p>1. Postfix设置不正确<br />2. 线路不好, 影响传送<br />3. MSS值太小<br /><br />修改了postfix的发送超时参数, 症状依旧. 因为之前附件发送还是可以用的, 所以很快排除postfix的原因.&nbsp;</p><p>接下来考虑线路问题. 修了默认路由, 分别测试了3条线路, 用速度最快的一条做mail出口. 并在mail server上wget, 一直稳定在120K左右, 基本可以排除线路的问题了</p><p><a target="_blank" href="http://blog.bigcomic.com/upload/emerr_2.png"><img height="141" alt="" width="600" border="0" src="http://blog.bigcomic.com/upload/emerr_2.png" /></a><br />图-2</p><p>但是连接到美国smtp时速度很慢, 这非常象MSS过小的症状. </p><p><a target="_blank" href="http://blog.bigcomic.com/upload/emerr_4.png"><img height="255" alt="" width="600" border="0" src="http://blog.bigcomic.com/upload/emerr_4.png" /></a><br />图-3</p><p><br />前几天刚刚用ROS做了负载均衡路由,可能是ROS的MSS设置有问题.&nbsp; 在mangle表里做了change MSS操作. 依旧是发不出去信. </p><p><a target="_blank" href="http://blog.bigcomic.com/upload/emerr_3.png"><img alt="" border="0" src="http://blog.bigcomic.com/upload/emerr_3.png" /></a><br />图-4</p><p>无奈了.&nbsp; 这时旁边的兄弟抱怨: 连接网站怎么这么慢.&nbsp; 突然想到 我给各个部门做了queue. 而mail server也在其中.会不会是这个原因呢?&nbsp; 把upload和download 的max limit都设置为unlimited.&nbsp;&nbsp;信依旧发不出去. 旁边的兄弟依旧喊慢.</p><p>看了一下filter rules&nbsp;&nbsp;有几条drop规则. 其中一条是DROP内容有mp的数据包.&nbsp;(本意是禁止用户下载mp3,mp4之类的文件) 再回头看一下丢包的地方. 图5中红圈里就是mp, ros把这个包给丢了, 当然要超时.<br /><br /><a target="_blank" href="http://blog.bigcomic.com/upload/emerr_5.png"><img height="37" alt="" width="600" border="0" src="http://blog.bigcomic.com/upload/emerr_5.png" /></a><br />图-5</p><p>disable那个规则, &nbsp;这时马上提示有新邮件. 一看都是我发送的测试邮件.&nbsp; 至此问题解决.&nbsp; <br /><br />以后做filter时一定要很小心很小心, 否则就是给自己找麻烦了 - -!</p><p><a target="_blank" href="http://blog.bigcomic.com/upload/mail_err.rar">分析过程的数据包下载</a></p><p>&nbsp;</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/215.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=215</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=215&amp;key=ecba55d3</trackback:ping></item><item><title>利用蓝牙让电脑通过手机上网的方法</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/213.html</link><pubDate>Tue, 19 Feb 2008 22:49:32 +0800</pubDate><guid>http://blog.bigcomic.com/post/213.html</guid><description><![CDATA[　　我是试过电脑通过手机蓝牙上网，但没试过笔记本，估计应该是一样的吧。<br/><br/>　　第一种方法：这种方法最简单实用。首先电脑中安装蓝牙适配器驱动，将蓝牙适配器插入USB端口，然后，打开手机蓝牙，由电脑蓝牙进行搜索蓝牙设备，搜索到设备后，双击该设备图标，此时电脑蓝牙设备中的拔号网络服务等显示为黄色边框（成为黄色后为激活状态，可以会因为蓝牙品牌不同色彩方式不同），然后你对着拔号网络服务图标右键选择连接，会跳出来一拔号对话框，用户名和密码为空，拔号为*99***1#。然后点击拔号就会自动连接网络。<br/><br/>　　通过以上步骤，在电脑的开始-拔号连接中，已经自动建立了拔号网络（和宽带拔号那个一样的图标），以后只需要将手机与电脑适配器配对后，直接点击Bluetooth DUN Connection就可以直接拔号，Bluetooth DUN Connection拔号网络可以建快捷方式到电脑桌面上。<br/><br/>　　第二种方法：这种方法相对复杂一些。按照上面的操作直到拔号网络及蓝牙串行端口图标为黄色边框后，你选连接串行端口，并记住这个端口的端口号（连接端口时，电脑会提示端口号），然后打开手机自带的PhoneSuite软件，在设定中选择你刚才记住的端口号，然后，软件右下方会出现已经连接的提示，你再选择建立联机，电信业者选第一个，然后点击建立联机，这时联机成功后，自动安装拔号调制器，提示成功后，你进入拔接，会看到新出现的拔号网络GPRS-CHINA-MOBILE，你选择它并点击拔接按钮，就开始拔号上网了，同时，也可用此方法实现手机用数据线连接电脑备份恢复电话簿管理文件等一样的工作。<br/><br/>　　同样，通过以上步骤，在电脑的开始-拔号连接中，已经自动建立了拔号网络（和宽带拔号那个一样的图标）GPRS_China_MOBILE，以后只需要打开PhoneSuite软件、电脑蓝牙与手机蓝牙串行端口连接后，直接点击GPRS_China_MOBILE就可以直接拔号，GPRS_China_MOBILE拔号网络可以建快捷方式到电脑桌面上。<br/><br/>　　最后，提醒大家，电脑通过手机上网，会产生大流量的数据，所以，没有全包月的用户，慎用。<br/>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/213.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=213</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=213&amp;key=0148f4f5</trackback:ping></item><item><title>iPAQ掌上电脑与蓝牙手机GPRS上网操作要点</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/212.html</link><pubDate>Tue, 19 Feb 2008 22:48:39 +0800</pubDate><guid>http://blog.bigcomic.com/post/212.html</guid><description><![CDATA[iPAQ掌上电脑与蓝牙手机GPRS上网操作要点<br/><br/>H3800/H3900: <br/><br/>1. 蓝牙通讯启动之后, 注意用手机来匹配iPAQ, 先在手机一端输入识别码, 在iPAQ一端会自动弹出识别码窗口 <br/><br/>2. 手机: 选择"数据通信" 服务, 建立一个GPRS帐户, 命名, 然后输入APN: Cmnet <br/><br/>3. 匹配成功之后, 在iPAQ蓝牙管理器中点击匹配好的手机图标,检查"已绑定设备" 一栏是否为"是", <br/><br/>如果为"是", 则说明绑定关系已建立, 左角有个"操作"菜单, 点开之后应有一些服务选项, <br/><br/>点击"设置为Internet 拨号连接"； 如果"已绑定设备"显示为"是", 但在操作菜单中却找不到任何服务, 则须从手机一侧重新匹配. <br/><br/>4. iPAQ: 开始----设置------连接-----连接-----------拨号位置-----"国家代码"和"地区代码"均为空--------点击"拨号模式", 将三个选项全部改为"G". <br/><br/>5. iPAQ: 开始-设置----连接----连接----更改----新建一个蓝牙拨号连接, 选择"Bluetooth dialup modem", "国家代码"和"地区代码"均为空, 电话号码为"*99#" <br/><br/>.H5450/H5550:蓝牙匹配设置与1. 2.相同 <br/><br/>iPAQ: 开始----设置------连接-----连接-----------拨号位置-----"国家代码"和"地区代码"均为空--------点击"拨号模式", 将三个选项全部改为"G". <br/><br/>请大家注意针对H5450和H2210, H5550, 不要在开始--设置---连接---连接里建立蓝牙连接, <br/><br/>这种方法必须输入地区代码和国家代码否则无法执行下一步, 因而会导致显示"已经连接"但IE却没有流量, 或根本连接不上. <br/><br/>必须用下面的步骤建立蓝牙拨号连接: <br/><br/>Bluetooth Manager---点击"新建"- 点击"连接"----选择"连接到Internet <br/><br/>(使用网络接入点, 移动电话或连接的另一个Bluetooth设备设备访问Internet".---- 点击"下一步"---- <br/><br/>选择"通过移动电话或连接到计算机上的共享调制解调器等拨号设备进行连接.----下一步------ <br/><br/>敲击"设备"下面的方框, 等待Bluetooth浏览器找到手机设备.----点击找到的手机图标, <br/><br/>Bluetooth 连接向导将创建一个连接快捷方式----点击"完成"--- 点击"OK" <br/><br/>( 此时在"连接--设置 "里将会增加一个Bluetooth设置的选项)----屏幕上出现"Bluetooth: 新建拨号连接"的界面, <br/><br/>起名, 国家代码和地区代码为空, 输入*99#. ---- 开始拨号 <br/><br/>H2210/H1900: <br/><br/>蓝牙匹配设置与1. 2.相同iPAQ: 开始-设置 ---连接---连接---高级----选择位置----- <br/><br/>在"使用拨号规则"选项前面打勾---"选择当前拨号位置"设置成"单位", <br/><br/>点击"编辑"按钮---地击"拨号模式"按钮---将三个选项全部改为"G". <br/><br/>蓝牙管理器中的设置与H5450相同如果以上方式GPRS上网依然不成功, <br/><br/>请尝试下列办法:对于索爱手机系列, 检查手机上的CID设置:CID=1, <br/><br/>将拨号号码改为: *99***1#CID=2, 将拨号号码改为 *99***2# <br/><br/>对于非索爱系列的手机, 如果手机菜单中没有CID的设置, <br/><br/>请检查"连接设置" 选项目:确定您当前使用的连接序列号, 采用与之相对应的拨号号码, <br/><br/>例如连接设置----------- 拨号号码 <br/><br/>1 --------------------*99***1# <br/><br/>2 --------------------*99***2# <br/><br/>3 --------------------*99***3# <br/><br/>4 --------------------*99***4# <br/><br/>5 --------------------*99***5# <br/><br/>对于下列手机型号, <br/><br/>请尝试在iPAQ上设置额外拨号命令:Nokia 3650+CGDCONT=1 ，“ IP ”，空格“ cmnet ”，拨号是 * 99 ***1# <br/><br/>西门子的手机（ 3618 、 6618 ）+CGDCONT=1 ，“ IP ”，空格“ cmnet ”，拨号是 * 99 ***1# <br/><br/>摩托罗拉 v600+CGDCONT=2 ，“ IP ”，空格“ cmnet ”，空格“ 0.0.0.0 ”，空格 0 ， 0 <br/><br/>索爱T68: <br/><br/>+CGDCONT=4，“IP”，空格“cmnet”,拨号号码＊99＊＊＊4#<br/>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/212.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=212</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=212&amp;key=5ef25ed9</trackback:ping></item><item><title>rsync认证的问题说明</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/206.html</link><pubDate>Mon, 03 Dec 2007 14:00:50 +0800</pubDate><guid>http://blog.bigcomic.com/post/206.html</guid><description><![CDATA[配置如下： /etc/rsyncd.conf <br/><br/>pid file = /var/run/rsyncd.pid<br/>use chroot = yes<br/>read only = yes<br/>secrets file = /etc/rsyncd.secrets<br/><br/>[gentoo-portage]<br/>path = /usr/portage<br/>comment = Gentoo Portage tree<br/>exclude = /distfiles /packages<br/>auth users = kangkang<br/>/etc/rsync.secrets <br/><br/>kangkang:pass <br/><br/>如果 /etc/rsync.secrets 权限不是0600，则会出现如下错误： <br/>$ rsync rsync://kangkang@localhost/gentoo-portage/ <br/>@ERROR: auth failed on module gentoo-portage rsync error: error starting client-server protocol (code 5) at main.c(1383) [receiver=2.6.9] <br/><br/>另外，推荐用上述格式书写rsync协议的命令，如使用 <br/><br/>rsync kangkang@localhost::gentoo-portage<br/>少输入一个`:'时： <br/><br/>rsync kangkang@localhost:gentoo-portage<br/>rsync会使用系统的远程shell认证，现在一般情况会使用ssh，这不是我们所期待的<br/>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/206.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=206</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=206&amp;key=b73578b4</trackback:ping></item><item><title>RFC821</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/196.html</link><pubDate>Tue, 06 Nov 2007 12:58:07 +0800</pubDate><guid>http://blog.bigcomic.com/post/196.html</guid><description><![CDATA[组织：中国互动出版网（http://www.china-pub.com/）<br/>RFC文档中文翻译计划（http://www.china-pub.com/compters/emook/aboutemook.htm）<br/>E-mail：ouyang@china-pub.com<br/>译者：顾国飞（ggfei  ggfei@263.net）<br/>译文发布时间：2001-3-30<br/>版权：本中文翻译文档版权归中国互动出版网所有。可以用于非商业用途自由转载，但必须保留本文档的翻译及版权信息。<br/><br/>Network Working Group                                          J. Postel<br/>Request for Comments: DRAFT                                          ISI<br/>Replaces: RFC 788, 780, 772                                  August 1982<br/><br/><br/>RFC821 简单邮件传输协议（SMTP）<br/>(RFC821  SIMPLE MAIL TRANSFER PROTOCOL)<br/><br/><br/>目录<br/>1. 介绍	2<br/>2. SMTP模型	3<br/>3. SMTP过程	4<br/>3.1. MAIL	4<br/>3.2. 转发	5<br/>3.3. 确认和扩展	6<br/>3.4. 发送信件(mailing)和获得信件(sending)	7<br/>3.5. 打开和关闭	7<br/>3.6. 转发	8<br/>3.7. 域	9<br/>3.8. 改变角色	9<br/>4. SMTP说明	9<br/>4.1. SMTP命令	9<br/>4.1.1. 命令语法	9<br/>4.1.2. COMMAND语法格式	13<br/>4.2. SMTP响应	15<br/>4.3. 命令和应答序列	16<br/>4.4. 状态图	17<br/>4.5. 详细内容	18<br/>4.5.1. 最小实现	18<br/>4.5.2. 透明性	19<br/>4.5.3. 大小	19<br/>附录 A TCP传输服务	19<br/>附录 B NCP传输服务	20<br/>附录 C NITS	20<br/>附录 D X.25传输服务	20<br/>附录 E 应答码构成方法	20<br/>附录 F 一些例子	22<br/>参考资料	36<br/><br/>  1. 介绍<br/>　　简单邮件传输协议（SMTP）的目标是可靠高效地传送邮件，它独立于传送子系统而且仅要求一条可以保证传送数据单元顺序的通道。附录A，B，C和D描述了不同传送服务下SMTP的使用。在名词表中还定义了本文档中使用的术语。<br/>　　SMTP的一个重要特点是它能够在传送中接力传送邮件，传送服务提供了进程间通信环境（IPCE），此环境可以包括一个网络，几个网络或一个网络的子网。理解到传送系统（或IPCE）不是一对一的是很重要的。进程可能直接和其它进程通过已知的IPCE通信。邮件是一个应用程序或进程间通信。邮件可以通过连接在不同IPCE上的进程跨网络进行邮件传送。更特别的是，邮件可以通过不同网络上的主机接力式传送。<br/>2. SMTP模型 <br/>　　SMTP设计基于以下通信模型：针对用户的邮件请求，发送SMTP建立与接收SMTP之间建立一个双向传送通道。接收SMTP可以是最终接收者也可以是中间传送者。SMTP命令由发送SMTP发出，由接收SMTP接收，而应答则反方面传送。<br/>一旦传送通道建立，SMTP发送者发送MAIL命令指明邮件发送者。如果SMTP接收者可以接收邮件则返回OK应答。SMTP发送者再发出RCPT命令确认邮件是否接收到。如果SMTP接收者接收，则返回OK应答；如果不能接收到，则发出拒绝接收应答（但不中止整个邮件操作），双方将如此重复多次。当接收者收到全部邮件后会接收到特别的序列，如果接收者成功处理了邮件，则返回OK应答。<br/>SMTP提供传送邮件的机制，如果接收方与发送方连接在同一个传送服务下时，邮件可以直接由发送方主机传送到接收方主机；或者，当两者不在同一个传送服务下时，通过中继SMTP服务器传送。为了能够对SMTP服务器提供中继能力，它必须拥有最终目的主机地址和邮箱名称。<br/>　　MAIL命令参数是回复路径，它指定邮件从何处来；而RCPT命令的参数是转发路径的，它指定邮件向何处去。向前路径是源路径，而回复路径是返回路径（它用于发生错误时返回邮件）。<br/>　　当同一个消息要发往不同的接收者时，SMTP遇到了向不同接收者发送同一份数据的复制品的问题，邮件命令和应答有一个比较奇怪的语法，应答也有一个数字代码。在下面，例子中可以看到哪些使用实际的命令和应答。完整的命令和应答在第四节。<br/>　　命令与应答对大小写不敏感，也就是说，命令和应答可以是大写，小写或两者的混合，但这一点对用户邮件名称却不一定是对的，因为有的主机对用户名大小写是敏感的。这样SMTP实现中就将用户邮箱名称保留成初始时的样子，主机名称对大小写不敏感。<br/>　　命令与应答由ASCII字母表组成，当传送服务提供8位字节传送通道，每7位字符正确传送，而最高位被填充为0。当指定一般的命令或应答格式后，参数会由一些类似于语言的字符串表示出来，如"<string>"或"<reverse-path>"，这里尖括号表示这是一种类似于语言的变量。<br/>3. SMTP过程 <br/>　　本节提供了SMTP中的一些过程。头一个说明的是基本发送过程（定义为发送操作）。下来描述向前传送邮件，确认邮箱名称和扩展邮件列表，发送到终端和打开关闭交换。在本节的最后是对中断，邮件域的说明。本节的例子只是一部分命令和应答的序列，完整的例子见附录F。<br/>3.1. MAIL<br/>　　在SMTP发送操作中有三步，操作由MAIL命令开始给出发送者标识。一系列或更多的RCPT命令紧跟其后，给出了接收者信息，然后是DATA命令列出发送的邮件内容，最后邮件内容指示符确认操作。<br/><br/>　　过程中的第一步是MAIL命令，< reverse-path >包括源邮箱。<br/><br/>　　MAIL <SP> FROM:<reverse-path> <CRLF><br/><br/>　　此命令告诉接收者新的发送操作已经开始，请复位所有状态表和缓冲区。它给出反向路径以进行错误信息返回。如果请求被接收，接收方返回一个250 OK应答。<reverse-path>中不止包括了邮箱，它包括了主机和源邮箱的反向路由，其中的第一个主机就是发送此命令的主机。<br/><br/>　　过程中的第二步是发送RCPT命令。<br/><br/>　　RCPT <SP> TO:<forward-path> <CRLF><br/><br/>　　此命令给出向前路径标识接收者，如果命令被接收，接收方返回一个250 OK应答，并存储向前路径。如果接收者未知，接收方会返回一个550 Failure应答。此过程可能会重复若干次。<br/>　　<forward-path>不仅包括邮件，它是主机和目的邮箱的路由表，在其中的第一个主机就是接收命令的主机。 过程中的第三步是发送DATA命令。<br/><br/>DATA <CRLF><br/><br/>　　如果命令被接收，接收方返回一个354 Intermediate应答，并认定以下的各行都是信件内容。当信件结尾收到并存储后，接收者发送一个250 OK应答。因为邮件是在传送通道上发送，因此必须指明邮件内容结尾，以便应答对话可以重新开始。SMTP通过在最后一行仅发送一个句号来表示邮件内容的结束，在接收方，一个对用户透明的过程将此符号过滤掉，以不影响正常的数据。<br/>　　注意：邮件内容包括如下提示：Date, Subject, To, Cc, From。<br/><br/>　　邮件内容指示符确认邮件操作并告知接收者可以存储和再发送数据了。如果此命令被接收，接收方返回一个250 OK应答。DATA命令仅在邮件操作未完成或源无效的情况下失败。<br/><br/>　　上面所述的过程是一个发送操作。这些命令只能以上面的顺序使用。下例表示了在一个发送操作中这些命令的使用。<br/>　　SMTP过程例子 此例是在Alpha.ARPA主机的Smith发送邮件给Beta.ARPA主机的Jones，Green和Brown的，这里假定主机Alpha与主机Beta直接相连。<br/><br/>　　S: MAIL FROM:<Smith@Alpha.ARPA><br/>　　R: 250 OK<br/>　　S: RCPT TO:<Jones@Beta.ARPA><br/>　　R: 250 OK<br/>　　S: RCPT TO:<Green@Beta.ARPA><br/>　　R: 550 No such user here<br/>　　S: RCPT TO:<Brown@Beta.ARPA><br/>　　R: 250 OK<br/>　　S: DATA<br/>　　R: 354 Start mail input; end with <CRLF>.<CRLF><br/>　　S: Blah blah blah...<br/>　　S: ...等等<br/>　　S: <CRLF>.<CRLF><br/>　　R: 250 OK<br/>　　此信被前两个人接收，而第三个人在此主机上没有邮箱。<br/>3.2. 转发 <br/>　　下面是一些<forward-path>中目的地址不正确的，但接收者知道正确的目的地址的例子。在这些例子中，下列应答之一应该允许发送方与获得正确地址。<br/><br/>　　251：用户不在本地；将向前发送到<forward-path>。<br/><br/>　　这个应答意味着，接收方SMTP知道用户的邮箱在另外的主机上，而且意味着将在未来使用正确的转向路径。请注意，主机或者用户，或者它们两者是不同的。接收方负责传送消息。<br/><br/>　　551 ：用户非本地，请尝试<forward-path><br/><br/>　　这个应答意味着接收SMTP知道用户的邮箱在另外的主机上，并意味着使用了正确的转发路径。注意请注意，主机或者用户，或者它们两者是不同的。接收方拒绝接收此用户的信件，发送者必须根据提供的信息重新发送或者向原发送者返回错误信息。 下例显示了这些响应的应用。<br/><br/>　　转发的例子<br/>　　S: RCPT TO:<Postel@USC-ISI.ARPA>　　R: 251 User not local; will forward to <Postel@USC-ISIF.ARPA>　　或者<br/>　　S: RCPT TO:<Paul@USC-ISIB.ARPA>　　R: 551 User not local; please try <Mockapetris@USC-ISIF.ARPA><br/>3.3. 确认和扩展<br/>　　SMTP提供了另外的确认用户名和扩展邮件列表的功能。这些功能由VREF和EXPN命令完成，它们都以字符串为参数。对于VREF命令，字符串参数指的是用户名，对此命令的响应要包括用户的命名和用户的邮箱。对于EXPN命令，字符串参数指的是邮件列表，对此命令的响应多于一个，它们要包括所有列表中用户的命名和他们的邮箱。<br/>　　“用户名”是一个多余的项目，它是故意被加上的。如果主机采用VREF命令和EXPN命令，最后本地邮箱必须提供用户名使它被主机确认。如果主机选择由另外的字符串作为用户名，也是允许的。<br/>　　在一些主机中，邮箱列表和一个邮箱的代名有一点不清楚，因为一般的数据结构可能包括两种类型的入口。如果要发出对邮件列表的确认，应该给出确定响应。在接收到这个消息后，主机将把邮件传送到列表上所有的地址上去，如果没有接收到确定响应，就会报告错误。例如，"550 That is a mail list, not a user name"。如果请求用于扩展一个用户名，可能通过返回包括一个名字的列表来形成确定响应，如果没有接收到确定响应，就会报告错误。（例如， "550 That is a user name, not a mailing list"）。<br/>　　在多个响应的情况下（通常是对于EXPN而言的），每个应答指定一个邮箱。在模糊请求的情况下，例如"VRFY Smith"，这里两个Smith的响应必须是"553 User ambiguous"。<br/><br/>　　确认用户名的情况如下例所示：例3：<br/>　　确认用户名<br/>　　S: VRFY Smith R: 250 Fred Smith <Smith@USC-ISIF.ARPA><br/>　　或者<br/>　　S: VRFY Smith<br/>　　R: 251 User not local; will forward to <Smith@USC-ISIQ.ARPA><br/>　　或者<br/>　　S: VRFY Jones<br/>　　R: 550 String does not match anything.<br/>　　或者<br/>　　S: VRFY Jones<br/>　　R: 551 User not local; please try <Jones@USC-ISIQ.ARPA><br/>　　或者<br/>　　S: VRFY Gourzenkyinplatz<br/>　　R: 553 User ambiguous.<br/><br/>　　邮箱列表要求多个响应的情况如下例所示：<br/>　　S: EXPN Example-People<br/>　　R: 250-Jon Postel <Postel@USC-ISIF.ARPA>　　R: 250-Fred Fonebone <Fonebone@USC-ISIQ.ARPA><br/>　　R: 250-Sam Q. Smith <SQSmith@USC-ISIQ.ARPA><br/>　　R: 250-Quincy Smith <@USC-ISIF.ARPA:Q-Smith@ISI-VAXA.ARPA><br/>　　R: 250-<joe@foo-unix.ARPA><br/>　　R: 250 <xyz@bar-unix.ARPA><br/>　　或者<br/>　　S: EXPN Executive-Washroom-List<br/>　　R: 550 Access Denied to You.<br/><br/>　　VERF和EXPN命令的字符串命令参数因为具体实现的不同而不能再加以限制了。在一些系统上，EXPN命令的参数可能是一个包含邮件列表的文件名，但是在Internet上有许多不同的文件结构。<br/>　　VRFY和EXPN命令在最小实现中并不包括，当它们实现时，它们也不要求被在传送间实现。　<br/>3.4. 发送信件(mailing)和获得信件(sending) <br/>　　SMTP的主要目的是将邮件发送到用户的邮箱中。由一些主机提供的类似的功能是把邮件送至用户的终端（如果用户正打开终端）。将邮件送到用户的邮箱中称为发送信件（mailing）；而送至用户终端则称之为获得信件（sending）。因为在一些主机上，这两者的实现十分类似，所以它们同时被放入了SMTP中。然而，获得信件命令在SMTP的最小实现中是没有的。用户应该具有控制向终端上写信息的能力。大部分主机允许用户接受或者拒绝类似的信息。<br/>　　下面三个命令被定义来支持获得信件。它们被用于邮件命令而不是MAIL命令，指示接收SMTP这种操作的特殊意义：<br/>　　SEND <SP> FROM:<reverse-path> <CRLF><br/>　　SEND命令要求邮件内容直接传送到用户终端。如果用户未打开终端（或者未接收终端信息），450响应将返回一个RCPT命令。如果信息被成功发送，此操作成功。　<br/>　　SOML <SP> FROM:<reverse-path> <CRLF>　<br/>　　Send或者MaiL命令要求将邮件内容直接发送到用户的终端上（如果用户在终端上）。如果用户不在终端上，邮件内容直接进入邮箱。如果邮件被发送到用户终端或者用户信箱，发送操作成功。　<br/>　　SAML <SP> FROM:<reverse-path> <CRLF><br/>　　Send和MaiL命令要求邮件内容直接发送到用户终端上（如果用户在终端上）。不管怎么样，信件都会进入信箱。如果信件进入信箱，发送操作成功。<br/>　　用于MAIL命令的响应和这些命令的响应相同。 　<br/>3.5. 打开和关闭 <br/>　　当打开传送通道时，要交换一些信息以确定双方的身份。以下的命令是用于打开和关闭的：<br/>　　HELO <SP> <domain> <CRLF><br/>　　QUIT <CRLF><br/>　　在HELLO命令中，主机自己发送命令，此命令可以被解释为：“你好，我是XX"。<br/><br/>　　打开联结的例子<br/>　　R: 220 BBN-UNIX.ARPA Simple Mail Transfer Service Ready<br/>　　S: HELO USC-ISIF.ARPA<br/>　　R: 250 BBN-UNIX.ARPA<br/><br/>　　关闭联结的例子<br/>　　S: QUIT<br/>　　R: 221 BBN-UNIX.ARPA Service closing transmission channel<br/>3.6. 转发<br/>　　转发路径可能是如下格式："@ONE,@TWO:JOE@THREE"，在这里，ONE，TWO和THREE是主机。这种格式用于强调地址和路径的区别。邮箱是绝对地址，路径是关于如何到达的信息。这两个概念不应该被混淆。<br/>　　概念上，转发路径的元素被移动到回复路径作为从一个SMTP服务器到另一个SMTP服务器的信息。回复路径是一个反向数据源路径，例如从当前信息的位置到发起者的位置。当一个SMTP服务器从转发路径中删除自己的标记并将它插入到回复路径中时，它必须使用它发送环境能够理解的名称来进行，以防它的名称在不同的环境中被理解为不同的名字。<br/>　　如果当SMTP接收到信息的转发路径的第一个元素不是此SMTP的标记时，此元素不从转发路径中删除，而被用来决定下一个应该发送到的SMTP服务器。在任何情况下，SMTP都将自己的标记加入反向路径中。<br/>　　使用源路径时，接收SMTP接收转发的邮件并发送到另一接收SMTP服务器上。接收服务器可以接受或拒绝转发本地用户的邮件。接收SMTP通过将它自己的标记从转发路径移至回复路径的开始处来改变命令参数。这时，接收SMTP变成了发送SMTP，也就建立了到下一个转发路径中SMTP的通道，然后，它向这个SMTP发送邮件。<br/>　　在回复路径上的头一个主机应是发送SMTP命令的主机，在转发路径上第一个主机应是接收SMTP命令的主机。<br/>　　注意：转发路径和回复路径出现在SMTP命令和应答中，但不一定要出现在信息中。也就是说，没有必须要这样的路径特别这种格式出现在信息头的"To:"，"From:"和"CC:"等域中。<br/>　　　如果SMTP服务器接受了转发任务，但后来它发现因为转发路径不正确或者其它原理无法发送邮件，它必须建立一"undeliverable mail"信号，将它此信号送到此信的发主者那里。<br/>　　此信号必须是从此主机的SMTP服务上发出的，当然了，此服务器不应该再报告出错信息的错误。一种阻止这种出错报告循环的情况是在信号的邮件命令的回复路径上置空。在传送此信息时，允许将回复路径也置为空。一个MAIL命令后的回复路径为空表现为如下形式：<br/>　　MAIL FROM:<><br/><br/>　　下例中显示了不可传送的邮件信息。此信息是对从HOSTW上的JOE发出的邮件经过在HOSTX需要经过HOSTZ到达HOSTY时出错的回应。我们看到的例子是在HOSTX和HOSTY之间发生的。<br/><br/>　　不可传送邮件信息的例子<br/>　　S: MAIL FROM:<><br/>　　R: 250 ok<br/>　　S: RCPT TO:<@HOSTX.ARPA:JOE@HOSTW.ARPA><br/>　　R: 250 ok<br/>　　S: DATA<br/>　　R: 354 send the mail data, end with .<br/>　　S: Date: 23 Oct 81 11:22:33<br/>　　S: From: SMTP@HOSTY.ARPA<br/>　　S: To: JOE@HOSTW.ARPA<br/>　　S: Subject: Mail System Problem<br/>　　S:<br/>　　S: Sorry JOE, your message to SAM@HOSTZ.ARPA lost.<br/>　　S: HOSTZ.ARPA said this:<br/>　　S: "550 No Such User"<br/>　　S: .<br/>　　R: 250 ok<br/>3.7. 域 <br/>　　域是最近被引入ARPA Internet邮件系统的。使用域可以使地址空间从一个平面的普通字符串主机名变成全局地址的一个层次结构。主机由一个域名取代，起始主机是由一系列元串组成，它们由逗号按最特殊到一般的顺序排列。<br/>　　例如，"USC-ISIF.ARPA"，"Fred.Cambridge.UK"和"PC7.LCS.MIT.ARPA"可能是主机-域标识符。<br/>　　无论域名在SMTP中如何使用，只有正式的名称才可以被使用，不可以使用假名或昵称。<br/>3.8. 改变角色<br/>　　TURN命令可以用来改变在传输信道上通信的程序的角色。如果程序A现在是发送SMTP，它发送TURN命令并接到OK应答（250）后，它就变为接收SMTP了。同理，程序B也可以从接收SMTP变为发送SMTP。若要拒绝改变角色，接收方可以发送502作为应答。<br/>　　注意：此命令是可选的。在使用TCP的传输信道时，一般不使用此命令。然而，当建立传输信道的代价比较大时，此命令很有用。例如，此命令可以支持一般公共交换电话系统作为传输信道。<br/>4. SMTP说明 <br/>4.1. SMTP命令 <br/>4.1.1. 命令语法 <br/>　　SMTP命令定义了邮件传输或由用户定义的系统功能。它的命令是由<CRLF>结束的字符串。而在带有参数的情况下，命令本身由<SP>和参数分开，如果未带参数可以直接和<CRLF>连接。邮箱的语法格式必须和接收站点的格式一致。下面讨论SMTP命令和应答。<br/>　　发送邮件操作涉及到不同的数据对象，它们由不同的参数相互连接。回复路径就是MAIL命令的参数，而转发路径则是RCPT命令的参数，邮件日期是DATA命令的参数。这些参数或者数据对象必须跟在命令后。这种模式也就要求有不同的缓冲区来存储这些对象，也就是说，有一个回复路径缓冲区，一个转发路径缓冲区，一个邮件内容缓冲区。特定的命令产生自己的缓冲区，或使一个或多个缓冲的内容被清除。<br/>　　HELLO (HELO)<br/>　　此命令用于向接收SMTP确认发送SMTP。参数域包括发送SMTP的主机名。接收SMTP通过连接确认命令来向发送SMTP确认接收SMTP。引命令和OK响应确认发送和接收SMTP进入了初始状态，也就是说，没有操作正在执行，所有状态表和缓冲区已经被子清除。<br/>　　MAIL (MAIL) <br/>　　此命令用于开始将邮件发送到一个多个邮箱中。参数域包括回复路径。返回路径中包括了可选的主机和发送者邮箱列表。当有主机列表时，它是一个回复路径源，它说明此邮箱是由在表中的主机一一传递发送（第一个主机是最后一个接收到此邮件的主机）过来的。此表也有作向发送者返回非传递信号的源路径。因为每个传递主机地址都被加在此表起始处，它就必须使用发送IPCE而不是接收IPCE（如果它们不是一个IPCE的话）清楚的名称。一些出错信息的回复路径可能就是空的。<br/>　　此命令清除回复路径缓冲区，转发路径缓冲区和邮件内容缓冲区，并且将此命令的回复路径信息插入到回复路径缓冲区中。<br/>　　RECIPIENT (RCPT)<br/>　　此命令用于确定邮件内容的唯一接收者；多个接收者将由多个此命令指定。转发路径中包括一个可选的主机和一个必须的目的邮箱。当出现主机列表时，这就是一个源路径，它指明邮件必须向列表中的上一个主机发送。如果接收SMTP未实现邮件的传递发送，就会返回如未知本地用户（550）的信息给用户。<br/>　　当邮件被传递发送时，传递主机必须将自己的名称由转发路径的开始处移至回复路径的结束处。当邮件最终到达目的地时，接收SMTP将以它的主机邮件格式自己的名称插入目标邮件中。例如，由传递主机A接收的带有如下参数的邮件时，<br/>　　FROM:<USERX@HOSTY.ARPA><br/>　　TO:<@HOSTA.ARPA,@HOSTB.ARPA:USERC@HOSTD.ARPA><br/>　　将会变成如下形式：<br/>　　FROM:<@HOSTA.ARPA:USERX@HOSTY.ARPA><br/>　　TO:<@HOSTB.ARPA:USERC@HOSTD.ARPA>.<br/>　　此命令导致它的转发路径参数加入转发路径缓冲区中。<br/>　　DATA (DATA)<br/>　　接收者将跟在命令后的行作为邮件内容。此命令导致此命令后的邮件内容加入邮件内容缓冲区。邮件内容可以包括所有128个ASCII码字符。邮件内容由只包括一个句号的行结束，也就是如下的字符序列："<CRLF>.<CRLF>"，它指示了邮件的结束。<br/>　　邮件内容的结束指示要求接收者现在就处理保存的邮件内容。此过程将回复路径缓冲区，转发路径缓冲区和邮件内容缓冲区的内容全部清空。如果操作成功，接收者必须返回OK应答；如果失败也必须返回失败应答。<br/>　　当接收SMTP收到一条信息时，无论是用作转发还是此邮件已经到达目的地，它都必须在邮件内容的开始处加上时间戳这一行，这一行指示了接收到邮件主机和发出此邮件主机的标识，以及接收到邮件内容的时间和日期。转发的信件将有多行这样的时间戳。当接收SMTP作最后一站的传送时，它将返回路径信息行插入邮件中。此行包括了发送命令中的<reverse-path>的信息。在这里，最后一站的传送的意思是邮件将被送到目的用户手中，但在一些情况下，邮件可能需要更进一步的加工并由另外的邮件系统传送。<br/>　　可能在返回路径中的邮箱与实际发送的邮件不一致，这个情况可能发生在需要传送一个特定的错误处理信箱而不是信件发送者那里。上面所述说明了，最后的邮件内容由一个返回路径行，和在其后的一个或多个时间戳行构成。这些行后面是邮件内容的头和体信息。<br/>　　当处理后面的邮件数据指示部分成功时就需要特定的说明。这种情况可能发生在发送SMTP发现当邮件需要传送给多个用户时，只能够成功地向其中的一部分发送信息这种情况下。在这种情况下，必须对DATA命令发送OK应答，而接收SMTP组织并发送一个"不可传递邮件"信息到信息的发送者。在此信息中或者发送一个不成功接收者的列表，或者每次发送一个不成接收者，而发送多次。所有不可传递邮件信息由MAIL命令发送。<br/>　　返回路径和接收时间戳例子<br/>　　Return-Path: <@GHI.ARPA,@DEF.ARPA,@ABC.ARPA:JOE@ABC.ARPA><br/>　　Received: from GHI.ARPA by JKL.ARPA ; 27 Oct 81 15:27:39 PST<br/>　　Received: from DEF.ARPA by GHI.ARPA ; 27 Oct 81 15:15:13 PST<br/>　　Received: from ABC.ARPA by DEF.ARPA ; 27 Oct 81 15:01:59 PST<br/>　　Date: 27 Oct 81 15:01:01 PST <br/>　　From: JOE@ABC.ARPA <br/>　　Subject: Improved Mailing System Installed <br/>　　To: SAM@JKL.ARPA <br/><br/>　　This is to inform you that ... <br/>　　SEND (SEND)<br/>　　此命令用于开始一个发送命令，将邮件发送到一个或多个终端上。参数域包括了一个回复路径，此命令如果成功就将邮件发送到终端上了。 <br/>　　回复路径包括一个可选的主机列表和发送者邮箱。当出现主机列表时，表示这是一个传送路径，邮件就是经过这个路径上的每个主机发送到这里的（列表上第一个主机是最后经手的主机）。此表用于返回非传递信号到发送者。因为每个传递主机地址都被加在此表起始处，它就必须使用发送IPCE而不是接收IPCE（如果它们不是一个IPCE的话）清楚的名称。一些出错信息的回复路径可能就是空的。<br/>　　此命令清除回复路径缓冲区，转发路径缓冲区和邮件内容缓冲区，并且将此命令的回复路径信息插入到回复路径缓冲区中。<br/>　　SEND OR MAIL (SOML)<br/>　　此命令用于开始一个邮件操作将邮件内容传送到一个或多个终端上，或者传送到邮箱中。对于每个接收者，如果接收者终端打开，邮件内容将被传送到接收者的终端上，否则就送到接收者的邮箱中。参数域包括回复路径，如果成功地将信息送到终端或邮箱中此命令成功。<br/>　　回复路径包括一个可选的主机列表和发送者邮箱。当出现主机列表时，表示这是一个传送路径，邮件就是经过这个路径上的每个主机发送到这里的（列表上第一个主机是最后经手的主机）。此表用于返回非传递信号到发送者。因为每个传递主机地址都被加在此表起始处，它就必须使用发送IPCE而不是接收IPCE（如果它们不是一个IPCE的话）清楚的名称。一些出错信息的回复路径可能就是空的。<br/>　　此命令清除回复路径缓冲区，转发路径缓冲区和邮件内容缓冲区，并且将此命令的回复路径信息插入到回复路径缓冲区中。<br/>　　SEND AND MAIL (SAML)<br/>　　此命令用于开始一个邮件操作将邮件内容传送到一个或多个终端上，并传送到邮箱中。如果接收者终端打开，邮件内容将被传送到接收者的终端上和接收者的邮箱中。参数域包括回复路径，如果成功地将信息送到邮箱中此命令成功。<br/>　　回复路径包括一个可选的主机列表和发送者邮箱。当出现主机列表时，表示这是一个传送路径，邮件就是经过这个路径上的每个主机发送到这里的（列表上第一个主机是最后经手的主机）。此表用于返回非传递信号到发送者。因为每个传递主机地址都被加在此表起始处，它就必须使用发送IPCE而不是接收IPCE（如果它们不是一个IPCE的话）清楚的名称。一些出错信息的回复路径可能就是空的。<br/>　　此命令清除回复路径缓冲区，转发路径缓冲区和邮件内容缓冲区，并且将此命令的回复路径信息插入到回复路径缓冲区中。<br/><br/>　　RESET (RSET)<br/>　　此命令指示当送邮件操作将被放弃。任何保存的发送者，接收者和邮件内容应该被抛弃，所有缓冲区和状态表应该被清除，接收方必须返回OK应答。<br/><br/>　　VERIFY (VRFY)<br/>　　此命令要求接收者确认参数是一个用户。如果这是（已经知道的）用户名，返回用户的全名和指定的邮箱。此命令对回复路径缓冲区，转发路径缓冲区和邮件内容缓冲区没有影响。<br/><br/>　　EXPAND (EXPN)<br/>　　此命令要求接收者确认参数指定了一个邮件发送列表，如果是一个邮件发送列表，就返回表中的成员。如果这是（已经知道的）用户名，返回用户的全名和指定的邮箱。此命令对回复路径缓冲区，转发路径缓冲区和邮件内容缓冲区没有影响。<br/><br/>　　HELP (HELP)<br/>　　此命令导致接收者向HELP命令的发送者发出帮助信息。此命令可以带参数，并返回特定的信息作为应答。此命令对回复路径缓冲区，转发路径缓冲区和邮件内容缓冲区没有影响。<br/><br/>　　NOOP (NOOP) <br/>　　此命令不影响任何参数和已经发出的命令。它只是说明没有任何操作而不是说明接收者发送了一个OK应答。此命令对回复路径缓冲区，转发路径缓冲区和邮件内容缓冲区没有影响。<br/><br/>　　QUIT (QUIT)<br/>　　此命令指示接收方必须发送OK应答然后关闭传送信道。接收方在接到QUIT命令并做出响应之前不应该关闭通信信道。发送方在发送QUIT命令和接收到响应之前也不应该关闭信道。即使出错，也不应该关闭信道。如果连接被提前关闭，接收方应该象接收到RSET命令一样，取消所有等待的操作，但不恢复原先已经做过的操作。而发送方应该象接收到暂时错误（4XX）一样假定命令和操作仍在支持之中。<br/><br/>　　TURN (TURN)<br/>　　此命令指定接收方要么发送OK应答并改变角色为发送SMTP，要么发送拒绝信息并保持自己的角色。如果程序A现在是发送SMTP，它发出TURN命令后接收到OK（250）应答，它就变成了接收SMTP。程序A就进入初始状态，好象通信信道刚打开一样，这时它发送220准备好服务信号。如果程序B现在是接收SMTP，它发出TURN命令后接收到OK（250）应答，它就变成了发送SMTP。程序A就进入初始状态，好象通信信道刚打开一样，这时它准备接收220准备好服务信号。<br/>若要拒绝改变角色，接收方可以发送502应答。<br/>　 对于这些命令的顺序有一定的限制。对话的第一个命令必须是HELLO命令，此命令在此后的会话中也可以使用。如果HELLO命令的参数不可接受，必须由返回一个501失败应答，同时接收到的SMTP必须保持在与刚才一致的状态下。 NOOP，HELP,EXPN和VRFY命令可以在会话的任何时候使用。MAIL，SEND，SOML或SAML命令开始一个邮件操作。一旦开始了以后就要发送RCPT和DATA命令。邮件操作可以由RSET命令终止。在一个会话中可以有一个或多个操作。<br/>　　如果在操作开始参数不可接受，必须返回501失败应答，同时接收到的SMTP必须保持在与刚才一致的状态下。如果操作中的命令顺序出错，必须返回503失败应答，同时接收到的SMTP必须保持在与刚才一致的状态下。<br/>会话的最后一个命令必须是QUIT命令。此命令在会话的其它时间不能使用。<br/>4.1.2. COMMAND语法格式<br/>　 命令是由命令码和其后的参数域组成的。命令码是四个字母组成的，不区别大小写。因为下面的命令的作用是相同的：<br/>　　MAIL Mail mail MaIl mAIl<br/>　　这对于引导任何参数值的标记也是适用的，如TO和to就是一样的。命令码和参数由一个或多个空格分开。然而在回复路径和转发路径中的参数是区别大小写的。特别是在一些主机上，"smith"和"Smith"就根本不是一个用户。<br/>参数域由不定长的字符串组成，它由<CRLF>结束，接收方在完全接收到此序列前不会采取任何行动。方括号代表可选的参数域。如果不选择的话，系统选择默认的设置。<br/>　　下面是SMTP命令： HELO <SP> <domain> <CRLF> MAIL <SP> FROM:<reverse-path> <CRLF><br/>RCPT <SP> TO:<forward-path> <CRLF><br/>DATA <CRLF><br/>RSET <CRLF><br/>SEND <SP> FROM:<reverse-path> <CRLF><br/>SOML <SP> FROM:<reverse-path> <CRLF><br/>SAML <SP> FROM:<reverse-path> <CRLF><br/>VRFY <SP> <string> <CRLF><br/>EXPN <SP> <string> <CRLF><br/>HELP [<SP> <string>] <CRLF><br/>NOOP <CRLF><br/>QUIT <CRLF><br/>TURN <CRLF><br/><br/>　　上面参数域的格式在下面给BNF的格式给出，其中的"..."代表对于一个域的一次或多次的重复。<br/><reverse-path> ::= <path><forward-path> ::= <path><path> ::= "<" [ <a-d-l> ":" ] <mailbox> ">"<br/><a-d-l> ::= <at-domain> | <at-domain> "," <a-d-l><br/><at-domain> ::= "@" <domain><br/><domain> ::= <element> | <element> "." <domain><br/><element> ::= <name> | "#" <number> | "[" <dotnum> "]"<br/><mailbox> ::= <local-part> "@" <domain><br/><local-part> ::= <dot-string> | <quoted-string><br/><name> ::= <a> <ldh-str> <let-dig><br/><ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str><br/><let-dig> ::= <a> | <d><br/><let-dig-hyp> ::= <a> | <d> | "-"<br/><dot-string> ::= <字符串> | <字符串> "." <dot-string><br/><字符串> ::= <字符> | <字符> <字符串><br/><quoted-string> ::= """ <qtext> """<br/><qtext> ::= "\" <x> | "\" <x> <qtext> | <q> | <q> <qtext><br/><字符> ::= <c> | "\" <x><br/><dotnum> ::= <snum> "." <snum> "." <snum> "." <snum><br/><number> ::= <d> | <d> <number><br/><CRLF> ::= <CR> <LF><br/><CR> ::= 回车符（ASCII码13） <LF> ::= （ASCII码10）<br/><SP> ::= 空格（ASCII码32） <snum> ::=由一个，两个或三个数字组成的介于0-255之间的数字<br/><a> ::= 所有A-Z的52个大小写英文字母<br/><c> ::= 128个ASCII字符，但不包括空格和特殊字符<br/><d> ::= 0-9数字<br/><q> ::=不包括<CR>，<LF>，"或\的128个ASCII字符<br/><x> ::=所有128个ASCII字符<br/><special> ::= "<" | ">" | "(" | ")" | "[" | "]" | "\" | "." | "," | ";" | ":" | "@" """ 或控制字符<br/>　　注意： "\"是一个转意字符，它表示在其后的字符代表另外的意义。例如"Joe\,Smith"用于表示单独一个由逗号分隔的用户名。主机通常由转化为地址的名称代表。注意：域的名称元素是正式的名称，不能够使用昵称或假名。<br/>有时候名称的转变机制可能不知道主机，这就造成了通信的阻塞。为了解决这个问题，可以采取两种方法：一种方法是：在"#"后加入一个十进制数表示主机地址；另一种方法是在其后加入32位的IP地址，IP地址的形式是由句号分隔的四个介于0-255之间的十进制数。时间戳行和返回路径行的格式通常由下面定义：<br/><return-path-line> ::= "Return-Path:" <SP><reverse-path><CRLF><br/><time-stamp-line> ::= "Received:" <SP> <stamp> <CRLF><br/><stamp> ::= <from-domain> <by-domain> <opt-info> ";" <daytime><br/><from-domain> ::= "FROM" <SP> <域> <SP><br/><by-domain> ::= "BY" <SP> <域> <SP><br/><opt-info> ::= [<via>] [<with>] [<id>] [<for>]<br/><via> ::= "VIA" <SP> <连接> <SP><br/><with> ::= "WITH" <SP> <协议> <SP><br/><id> ::= "ID" <SP> <字符串> <SP><br/><for> ::= "FOR" <SP> <路径> <SP><br/><连接> ::= 在网络信息中心注册的连接的标准名称<br/><协议> ::= 在网络中心注册的协议的名称<br/><daytime> ::= <SP> <日> <SP> <时间><br/><日期> ::= <日> <SP> <月> <SP> <年><br/><时间> ::= <小时> ":" <分> ":" <秒> <SP> <时区><br/><dd> ::= 由一个或两个数字组成的每月1-31日<br/><月> ::= "JAN" | "FEB" | "MAR" | "APR" | "MAY" | "JUN" | "JUL" | "AUG" | "SEP" | "OCT" | "NOV" | "DEC"<br/><年> ::= 由两位数字表示本世界的年代00-99<br/><小时> ::= 每天的24小时，由0到24<br/><分> ::= 每小时的分钟数0-59<br/><秒> ::= 每分钟的秒数0-59<br/><时区> ::= 全球标准时区<br/>返回路径例子<br/>Return-Path: <@CHARLIE.ARPA,@BAKER.ARPA:JOE@ABLE.ARPA><br/>时间戳行例子<br/>Received: FROM ABC.ARPA BY XYZ.ARPA ; 22 OCT 81 09:23:59 PDT<br/>Received: from ABC.ARPA by XYZ.ARPA via TELENET with X25<br/>id M12345 for Smith@PDQ.ARPA ; 22 OCT 81 09:23:59 PDT<br/>4.2. SMTP响应<br/>　　对SMTP命令的响应是多样的，它确定了在邮件传输过程中请求和处理的同步，也保证了发送SMTP知道接收SMTP的状态。每个命令必须有且只有一个响应。<br/>　　SMTP响应由三位数字组成，其后跟一些文本。数字帮助决定下一个应该进入的状态，而文本对人是有意义的。三位的响应已经包括了足够的信息，不用再阅读文本，文本可以直接抛弃或者传递给用户。特别的是，文本是与接收和环境相关的，所以每次接收到的文本可能不同。在附录E中可以看到全部的响应码。正规的情况下，响应由下面序列构成：三位的数字，<SP>，一行文本和一个<CRLF>，或者也可以是一个多行响应。只有EXPN和HELP命令可以导致多行应答，然而，对所有命令，多行响应都是允许的。<br/>4.2.1. REPLY CODES BY FUNCTION GROUPS 500 格式错误，命令不可识别（此错误也包括命令行过长）<br/>501 参数格式错误<br/>502 命令不可实现<br/>503 错误的命令序列<br/>504 命令参数不可实现<br/>211 系统状态或系统帮助响应<br/>214 帮助信息<br/>220 <domain> 服务就绪<br/>221 <domain> 服务关闭传输信道 <br/>421 <domain> 服务未就绪，关闭传输信道（当必须关闭时，此应答可以作为对任何命令的响应）<br/>250 要求的邮件操作完成<br/>251 用户非本地，将转发向<forward-path><br/>450 要求的邮件操作未完成，邮箱不可用（例如，邮箱忙）<br/>550 要求的邮件操作未完成，邮箱不可用（例如，邮箱未找到，或不可访问）<br/>451 放弃要求的操作；处理过程中出错<br/>551 用户非本地，请尝试<forward-path><br/>452 系统存储不足，要求的操作未执行<br/>552 过量的存储分配，要求的操作未执行<br/>553 邮箱名不可用，要求的操作未执行（例如邮箱格式错误）<br/>354 开始邮件输入，以<CRLF>.<CRLF>结束<br/>554 操作失败<br/>4.3. 命令和应答序列<br/>　　发送者和接收者之间的通信是一问一答的交替对话形式，由发送者控制。这样，发送发出一条命令，接收者发出一个响应。接收者在发送下一条指令前必须等应答。一个重要的应答是连接应答。在连接完成时，接收者通常会发送220"服务就绪"。发送者在继续发送指令前会等待此应答。注意：每个连接应答必须拥有服务主机的正式名称作为第一部分，其后跟响应码。例如：<br/>　　220 <SP> USC-ISIF.ARPA <SP> Service ready <CRLF><br/>　 下面列出了成功和失败应答，这些应答必须遵守严格的次序，接收者可以不理会应答中的文本，但是由数字指定的意义和操作和命令应答序列不能更改。命令响应序列： <br/>　　每个命令列出了它可能的应答。使用在可能应答前的前缀"P"表示预备的（未用在SMTP中），"I"表示中间的，"S"表示成功，"F"表示失败，"E"表示错误。如果STMP接收者必须关闭信道，可以对任何命令作出421（服务不可用，关闭传输信道）响应。此表基于下面要讲述的状态图：<br/>CONNECTION ESTABLISHMENT（建立连接）<br/>S: 220<br/>F: 421<br/>HELO<br/>S: 250<br/>E: 500, 501, 504, 421<br/>MAIL<br/>S: 250<br/>F: 552, 451, 452<br/>E: 500, 501, 421<br/>RCPT S: 250, 251 F: 550, 551, 552, 553, 450, 451, 452 E: 500, 501, 503, 421<br/>DATA<br/>I: 354 -> data -> S: 250<br/>F: 552, 554, 451, 452<br/>F: 451, 554<br/>E: 500, 501, 503, 421<br/>RSET<br/>S: 250<br/>E: 500, 501, 504, 421<br/>SEND<br/>S: 250<br/>F: 552, 451, 452<br/>E: 500, 501, 502, 421<br/>SOML<br/>S: 250<br/>F: 552, 451, 452<br/>E: 500, 501, 502, 421<br/>SAML<br/>S: 250<br/>F: 552, 451, 452<br/>E: 500, 501, 502, 421<br/>VRFY<br/>S: 250, 251<br/>F: 550, 551, 553<br/>E: 500, 501, 502, 504, 421<br/>EXPN<br/>S: 250<br/>F: 550<br/>E: 500, 501, 502, 504, 421<br/>HELP<br/>S: 211, 214<br/>E: 500, 501, 502, 504, 421<br/>NOOP<br/>S: 250<br/>E: 500, 421<br/>QUIT<br/>S: 221<br/>E: 500<br/>TURN<br/>S: 250<br/>F: 502<br/>E: 500, 503 <br/>4.4. 状态图<br/>　　下面状态图是一个简单的SMTP实现，每一组命令都有一个状态图。在图中，只使用了响应码的第一位数字作为响应的代表。命令组是对每个命令建立模式然后以结构模式将命令集中起来的。对于每个命令有三种可能的应答：成功（S），失败（F）和错误（E）。在状态中，我们使用B代表开始，使用W代表等待应答。<br/><br/><br/>　　　此状态图使用了如下命令：HELO, MAIL, RCPT, RSET, SEND, SOML, SAML, VRFY, EXPN, HELP, NOOP, QUIT, TURN.<br/>下面是对于DATA命令的更复杂的状态图：<br/><br/>　　注意：这里的邮件内容是多行的，接收者只能收到最后一行时才发出应答。<br/>4.5. 详细内容<br/>4.5.1. 最小实现<br/>　　为使SMTP能够工作，对于接收者来说，这是最少应该实现的命令：<br/>COMMANDS - HELO<br/>MAIL<br/>RCPT<br/>DATA<br/>RSET<br/>NOOP<br/>QUIT<br/>4.5.2. 透明性<br/>　　没有对数据透明性的保证，在发送类似"<CRLF>.<CRLF>"结束邮件内容时会发生错误。通常，用户不关心这个"非法"序列。若要所有用户能够透明地使用必须使用以下措施：<br/>1. 在发送邮件之间，发送SMTP必须检查邮件的每一行，如果是一个句号，就在行首再加一个句号。<br/>2. 当邮件被接收时，接收SMTP必须检查邮件的每一行，如果发现一行仅有一个句号，邮件就此结束，如果一行中有两个句号，那么这一行中就只应该有一个句号，而将第一个句号删除。<br/>　　发送的邮件内容可以包括所有128个ASCII字符。所有字符发送到收信者的邮箱，包括格式符号和其它控制字符。如果传输信道提供一个8位数据流，7位的ASCII码就可以在其中传送，而将最高位置为0。一些系统在接收和存储时需要对数据进行格式转换。对于使用不同于ASCII字符集的主机或不能以串的形式而只能以记录形式存储的主机更是如此，如果必须进行转换，必须能够再次转换回来，对于用于存储转发的主机更是如此。<br/>4.5.3. 大小<br/>　　一些对象需要最大和最小大小。也就是说，每个实现必须能够接收大于最小大小的对象，不能发送大于最大大小的对象。对于可能的最大大小，实现技术上并没有限制。<br/>用户 用户名的最大长度是64个字节。<br/>域 域的最大长度是64个字符<br/>路径 回复路径和转发路径的最大长度是256个字符<br/>命令行 命令行的最大长度，包括回车符为512个字符<br/>应答行 应答行的最大长度，包括回车符为512个字符<br/>文本行 文本行的最大长度，包括回车符和为透明性增加的字符不得超过1000个字符<br/>接收缓冲区 接收缓冲区最多可以容纳100个接收者<br/>如果出错，应答如下： <br/>500 行过长<br/>501 路径过多<br/>552 接收者过多<br/>552 邮件内容过多<br/>附录 A TCP传输服务 <br/>　　传输控制协议（TCP）在ARPA Internet中使用，并遵守网络协议的US DoD标准。SMTP传输信道连接建立在发送进程的端口U和接收进程的端口L上。一个单一的全双工信道用于传输。被指定用于此协议的服务端口为25，也就是说L=25。TCP连接支持传输8位字节，而SMTP只需要传输7位；这样，每个8位字符的最高位被置为0。<br/>附录 B NCP传输服务<br/>　　ARPANET主机-主机协议（由网络控制程序实现）也可以用于ARPANET。SMTP传输信道连接建立在发送进程的端口U和接收进程的端口L上；其后，根据初始连接协议（ICP）建立一对简单连接。这一对简单连接被用作传输信道。此协议被指定为连接套接字25，也就是说L=25。NCP连接支持传输8位字节，而SMTP只需要传输7位；这样，每个8位字符的最高位被置为0。<br/>附录 C NITS<br/>　　也可以使用网络独立转输服务。通过在NITS在发送进程和接收进程之间建立传输信道。发送进程执行CONNECT原语，然后等待接收ACCEPT原语。NITS连接支持传输8位字节，而SMTP只需要传输7位；这样，每个8位字符的最高位被置为0。<br/>附录 D X.25传输服务<br/>　　可以直接使用公共数据网络接收的X.25服务，然而，推荐在其上使用可靠的端到端的协议如TCP。<br/>附录 E 应答码构成方法<br/>　　三位的应答码每一位都有特定的意义。每一位应答表示是否是成功的，失败的或未完成的。通过这一位，不复杂的SMTP发送就可以决定下一步的操作，如果发送方希望大概了解究竟出了什么问题，它可以检测第二位，而第三位则保存了最后更完整的信息。也就是说，从第一位到第三位，接收方可以一步比一步精确地确定接收方的状态。对于第一位有五种可能的表示代表不同的意义：<br/><br/>　　1yz 部分完成应答<br/><br/>　　命令被接受，但是要求的操作被中止，原因在应答码中。发送方应该再次发送另一命令指明是否继续操作，或者放弃操作。<br/><br/>　　2yz 全部完成应答<br/><br/>　　要求的操作已经完成，可以开始另一个新的请求。<br/><br/>　　3yz 需要近一步信息的部分完成应答<br/><br/>　　命令被接受，但是要求的操作被中止，需要接收进一步的信息。发送方应该发送另一条命令指明进一步的信息。<br/><br/>　　4yz 暂时未完成应答<br/><br/>　　命令未被接受，要求的操作也未执行，但是发生错误的状态是暂时的，可以再一次请求操作。发送者应该返回命令序列的开始命令（如果有的话）。很难解释这个暂时的意义，特别对于两个不同的站点来说。区别应答是属于些类还是下一类的方法是：如果能够不加任何改变地重复的再一次发送命令，就是本类的，如果不是，就是下一类（5yz）的。<br/><br/>　　5yz 永久未完成应答<br/><br/>　　命令未被接受，要求的操作未完成。发送对命令的重复不起作用。即使一些出错条件已经改变，但是用户已经不希望重试，而希望在未来的某个时间再进行操作。<br/><br/>　　应答的第二位的意义有以下几类：<br/><br/>x0z 语法：此类型的应答是针对以下情况的：语法错误；符合语法但命令不存在功能；未完成或冗余的命令。<br/><br/>x1z 信息：此类型的应答是用于请求信息的，如状态或帮助信息。<br/><br/>x2z 连接：此类型的应答是关于传输信道的。<br/><br/>x3z 未使用。<br/><br/>x4z 未使用。<br/><br/>x5z 邮件系统：此类型的应答指明接收方邮件系统关于请求传送或其它操作的状态的。<br/><br/>　　第三位给出了更详细的说明。列出的应答表说明了这一点。文本应答是推荐使用的，而不是必须使用的，它的内容是可以根据不同情况而变化的。另一方面，应答码必须严格遵守本节的说明。接收方不应该因为稍稍的不同情况而自己创建新的代码而不使用已经定义的代码。例如，如NOOP命令的情况，如果成功执行它后，不用返回任何新的信息，只用返回250应答。当发送的命令要求一个未实现的站点指定操作时，应答应该是502。 应答文本可能多于一行；在此情况下，文本必须被标记，接收文本的一方才不致于少读入一行数据。这要求特定的格式说明多行应答。此格式是：每一行，除了最后一行外，都以应答码加一个"-"开始。而最后一行以应答码加空格<SP>开始。如下例：<br/><br/>123-First line<br/><br/>123-Second line<br/><br/>123-234 text beginning with numbers<br/><br/>123 The last line<br/><br/>　　通常情况下，接收的一方只用寻找应答码加空格的那一行就可以，而忽略前面行的内容。在特殊的情况下，发送方必须知道响应文本的内容，这时接收应答的一方可以通过当时的情况正确地决定是否需要知道文本的内容。 　<br/>附录 F 一些例子 <br/>本节提供了一些SMTP会话的完整例子。<br/><br/>典型的SMTP操作<br/><br/>此类显示邮件如何由在USC-ISIF和机上的Smith发送到BBN-UNIX主机上Jones，Green和Brown的。这里，我们假设USC-ISIF主机直接和BBN-UNIX主机联系。Jones和Brown接收邮件，而Green在BBN-UNIX上没有邮箱。<br/><br/>R: 220 BBN-UNIX.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO USC-ISIF.ARPA<br/><br/>R: 250 BBN-UNIX.ARPA<br/><br/>S: MAIL FROM:<Smith@USC-ISIF.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<Jones@BBN-UNIX.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<Green@BBN-UNIX.ARPA><br/><br/>R: 550 No such user here<br/><br/>S: RCPT TO:<Brown@BBN-UNIX.ARPA><br/><br/>R: 250 OK<br/><br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Blah blah blah...<br/><br/>S: ...etc. etc. etc.<br/><br/>S: .<br/><br/>R: 250 OK<br/><br/>　<br/><br/>S: QUIT<br/><br/>R: 221 BBN-UNIX.ARPA Service closing transmission channel<br/><br/>放弃SMTP操作 <br/><br/>R: 220 MIT-Multics.ARPA Simple Mail Transfer Service Ready <br/><br/>S: HELO ISI-VAXA.ARPA R: 250 MIT-Multics.ARPA <br/><br/>S: MAIL FROM:<Smith@ISI-VAXA.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<Jones@MIT-Multics.ARPA><br/><br/>R: 250 OK<br/>　<br/>S: RCPT TO:<Green@MIT-Multics.ARPA><br/><br/>R: 550 No such user here<br/><br/>S: RSET<br/><br/>R: 250 OK<br/><br/>S: QUIT<br/><br/>R: 221 MIT-Multics.ARPA Service closing transmission channel<br/><br/>转发邮件 <br/><br/>第一步：源主机到转发主机<br/><br/>R: 220 USC-ISIE.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO MIT-AI.ARPA<br/><br/>R: 250 USC-ISIE.ARPA<br/><br/>　<br/><br/>S: MAIL FROM:<JQP@MIT-AI.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<@USC-ISIE.ARPA:Jones@BBN-VAX.ARPA><br/><br/>R: 250 OK<br/><br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Date: 2 Nov 81 22:33:44<br/><br/>S: From: John Q. Public <JQP@MIT-AI.ARPA><br/><br/>S: Subject: The Next Meeting of the Board<br/><br/>S: To: Jones@BBN-Vax.ARPA<br/><br/>S:<br/><br/>S: Bill:<br/><br/>S: The next meeting of the board of directors will be<br/><br/>S: on Tuesday.<br/><br/>S: John.<br/><br/>S: .<br/><br/>R: 250 OK<br/><br/>S: QUIT<br/><br/>R: 221 USC-ISIE.ARPA Service closing transmission channel<br/><br/>第二步：转发主机到目的主机<br/><br/>R: 220 BBN-VAX.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO USC-ISIE.ARPA<br/><br/>R: 250 BBN-VAX.ARPA<br/><br/>S: MAIL FROM:<@USC-ISIE.ARPA:JQP@MIT-AI.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<Jones@BBN-VAX.ARPA><br/><br/>R: 250 OK<br/><br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Received: from MIT-AI.ARPA by USC-ISIE.ARPA ;<br/><br/>2 Nov 81 22:40:10 UT<br/><br/>S: Date: 2 Nov 81 22:33:44<br/><br/>S: From: John Q. Public <JQP@MIT-AI.ARPA><br/><br/>S: Subject: The Next Meeting of the Board<br/><br/>S: To: Jones@BBN-Vax.ARPA<br/><br/>S:<br/><br/>S: Bill:<br/><br/>S: The next meeting of the board of directors will be<br/><br/>S: on Tuesday.<br/><br/>S: John.<br/><br/>S: .<br/><br/>R: 250 OK<br/><br/>S: QUIT<br/><br/>R: 221 USC-ISIE.ARPA Service closing transmission channel<br/>确认和发送<br/><br/>R: 220 SU-SCORE.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO MIT-MC.ARPA<br/><br/>R: 250 SU-SCORE.ARPA<br/><br/>S: VRFY Crispin<br/><br/>R: 250 Mark Crispin <Admin.MRC@SU-SCORE.ARPA><br/><br/>S: SEND FROM:<EAK@MIT-MC.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<Admin.MRC@SU-SCORE.ARPA><br/><br/>R: 250 OK<br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Blah blah blah...<br/><br/>S: ...etc. etc. etc.<br/><br/>S: .<br/><br/>R: 250 OK<br/><br/>S: QUIT<br/><br/>R: 221 SU-SCORE.ARPA Service closing transmission channel<br/><br/>获得和发送邮件 首先确定用户名，然后尝试将邮件发送到用户终端，当它失败时，发送到用户邮箱。<br/><br/>R: 220 SU-SCORE.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO MIT-MC.ARPA<br/><br/>R: 250 SU-SCORE.ARPA<br/><br/>　<br/><br/>S: VRFY Crispin<br/><br/>R: 250 Mark Crispin <Admin.MRC@SU-SCORE.ARPA><br/><br/>S: SEND FROM:<EAK@MIT-MC.ARPA><br/><br/>R: 250 OK<br/>S: RCPT TO:<Admin.MRC@SU-SCORE.ARPA><br/><br/>R: 450 User not active now<br/><br/>S: RSET<br/><br/>R: 250 OK<br/><br/>S: MAIL FROM:<EAK@MIT-MC.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<Admin.MRC@SU-SCORE.ARPA><br/><br/>R: 250 OK<br/><br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Blah blah blah...<br/><br/>S: ...etc. etc. etc.<br/><br/>S: .<br/><br/>R: 250 OK<br/><br/>S: QUIT<br/><br/>R: 221 SU-SCORE.ARPA Service closing transmission channel<br/><br/>上述问题的更有效的作法 <br/><br/>R: 220 SU-SCORE.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO MIT-MC.ARPA<br/><br/>R: 250 SU-SCORE.ARPA<br/>S: VRFY Crispin<br/><br/>R: 250 Mark Crispin <Admin.MRC@SU-SCORE.ARPA><br/><br/>S: SOML FROM:<EAK@MIT-MC.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<Admin.MRC@SU-SCORE.ARPA><br/><br/>R: 250 User not active now, so will do mail.<br/><br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Blah blah blah...<br/><br/>S: ...etc. etc. etc.<br/><br/>S: .<br/><br/>R: 250 OK<br/><br/>S: QUIT<br/><br/>R: 221 SU-SCORE.ARPA Service closing transmission channel<br/><br/>　　邮件列表 首先，两个邮件列表中的每一个在不同主机的不同会话上扩展，然后，通过转发主机向列表上的用户发送邮件。<br/><br/>第一步：扩展第一个列表<br/><br/>R: 220 MIT-AI.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO SU-SCORE.ARPA<br/><br/>R: 250 MIT-AI.ARPA<br/><br/>　<br/><br/>S: EXPN Example-People<br/><br/>R: 250-<ABC@MIT-MC.ARPA><br/><br/>R: 250-Fred Fonebone <Fonebone@USC-ISIQ.ARPA><br/><br/>R: 250-Xenon Y. Zither <XYZ@MIT-AI.ARPA><br/><br/>R: 250-Quincy Smith <@USC-ISIF.ARPA:Q-Smith@ISI-VAXA.ARPA><br/><br/>R: 250-<joe@foo-unix.ARPA><br/><br/>R: 250 <xyz@bar-unix.ARPA><br/><br/>S: QUIT<br/><br/>R: 221 MIT-AI.ARPA Service closing transmission channel<br/>　<br/>第二步：扩展第二个列表 <br/><br/>R: 220 MIT-MC.ARPA Simple Mail Transfer Service Ready <br/><br/>S: HELO SU-SCORE.ARPA<br/><br/>R: 250 MIT-MC.ARPA<br/><br/>S: EXPN Interested-Parties<br/><br/>R: 250-Al Calico <ABC@MIT-MC.ARPA><br/><br/>R: 250-<XYZ@MIT-AI.ARPA><br/><br/>R: 250-Quincy Smith <@USC-ISIF.ARPA:Q-Smith@ISI-VAXA.ARPA><br/><br/>R: 250-<fred@BBN-UNIX.ARPA><br/><br/>R: 250 <xyz@bar-unix.ARPA><br/><br/>S: QUIT<br/><br/>R: 221 MIT-MC.ARPA Service closing transmission channel<br/><br/>　<br/><br/>第三步：通过转发主机向包括于两个列表中的所有用户发送邮件 <br/><br/>R: 220 USC-ISIE.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO SU-SCORE.ARPA<br/><br/>R: 250 USC-ISIE.ARPA<br/><br/>S: MAIL FROM:<Account.Person@SU-SCORE.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<@USC-ISIE.ARPA:ABC@MIT-MC.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<@USC-ISIE.ARPA:Fonebone@USC-ISIQA.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<@USC-ISIE.ARPA:XYZ@MIT-AI.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT<br/><br/>TO:<@USC-ISIE.ARPA,@USC-ISIF.ARPA:Q-Smith@ISI-VAXA.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<@USC-ISIE.ARPA:joe@FOO-UNIX.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<@USC-ISIE.ARPA:xyz@BAR-UNIX.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<@USC-ISIE.ARPA:fred@BBN-UNIX.ARPA><br/><br/>R: 250 OK<br/><br/>　<br/><br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Blah blah blah...<br/><br/>S: ...etc. etc. etc.<br/><br/>S: .<br/><br/>R: 250 OK<br/><br/>S: QUIT<br/><br/>R: 221 USC-ISIE.ARPA Service closing transmission channel<br/><br/>转发的情况<br/><br/>R: 220 USC-ISIF.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO LBL-UNIX.ARPA<br/><br/>R: 250 USC-ISIF.ARPA<br/><br/>S: MAIL FROM:<mo@LBL-UNIX.ARPA><br/><br/>R: 250 OK<br/>　<br/>S: RCPT TO:<fred@USC-ISIF.ARPA><br/><br/>R: 251 User not local; will forward to <Jones@USC-ISI.ARPA><br/><br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Blah blah blah...<br/><br/>S: ...etc. etc. etc.<br/><br/>S: .<br/><br/>R: 250 OK<br/>S: QUIT<br/><br/>R: 221 USC-ISIF.ARPA Service closing transmission channel<br/><br/>第一步：尝试第一台主机上的邮箱<br/><br/>R: 220 USC-ISIF.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO LBL-UNIX.ARPA<br/><br/>R: 250 USC-ISIF.ARPA<br/><br/>S: MAIL FROM:<mo@LBL-UNIX.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<fred@USC-ISIF.ARPA><br/><br/>R: 251 User not local; will forward to <Jones@USC-ISI.ARPA><br/>　<br/>S: RSET<br/><br/>R: 250 OK<br/>　<br/>S: QUIT<br/><br/>R: 221 USC-ISIF.ARPA Service closing transmission channel<br/><br/>第二步：尝试第二台主机上的邮箱<br/><br/>R: 220 USC-ISI.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO LBL-UNIX.ARPA<br/><br/>R: 250 USC-ISI.ARPA<br/><br/>S: MAIL FROM:<mo@LBL-UNIX.ARPA><br/><br/>R: 250 OK<br/>　<br/>S: RCPT TO:<Jones@USC-ISI.ARPA><br/><br/>R: OK<br/><br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Blah blah blah...<br/><br/>S: ...etc. etc. etc.<br/><br/>S: .<br/><br/>R: 250 OK<br/>　<br/>S: QUIT<br/><br/>R: 221 USC-ISI.ARPA Service closing transmission channel<br/><br/>许多接收者的情况<br/><br/>R: 220 BERKELEY.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO USC-ISIF.ARPA<br/><br/>R: 250 BERKELEY.ARPA<br/>　<br/>S: MAIL FROM:<Postel@USC-ISIF.ARPA><br/>R: 250 OK<br/>　<br/>S: RCPT TO:<fabry@BERKELEY.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<eric@BERKELEY.ARPA><br/><br/>R: 552 Recipient storage full, try again in another transaction<br/>　<br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Blah blah blah...<br/><br/>S: ...etc. etc. etc.<br/>S: .<br/><br/>R: 250 OK<br/><br/>　<br/><br/>S: MAIL FROM:<Postel@USC-ISIF.ARPA><br/>R: 250 OK<br/><br/>S: RCPT TO:<eric@BERKELEY.ARPA><br/><br/>R: 250 OK<br/><br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Blah blah blah...<br/><br/>S: ...etc. etc. etc.<br/><br/>S: .<br/><br/>R: 250 OK<br/><br/>S: QUIT<br/><br/>R: 221 BERKELEY.ARPA Service closing transmission channel<br/><br/>名词表:<br/><br/><CRLF><br/>回车<br/><br/><SP><br/>空格<br/><br/>ASCII<br/>美国标准信息交换码<br/><br/>主机<br/>拥有SMTP进程或邮箱的网络计算机<br/><br/>发送SMTP进程<br/>与接收SMTP进程一起工作的进程。发送SMTP开始传输服务连接，它发出SMTP命令，接收应答，管理邮件的传送<br/><br/>用户<br/>希望获得邮件服务的人（或以人的名义出现的进程），还有就是邮件的接收者。<br/><br/>会话<br/>当传输信道打开时进行的一系列信息交换<br/><br/>传输服务<br/>可靠的面向流的数据通信服务。例如：NCP，TCP，NITS。<br/><br/>传输信道<br/>在发送SMTP和接收SMTP之间建立的全双工的用于交换命令，应答和邮件内容的信道<br/><br/>字符<br/>可显示字符串<br/><br/>行<br/>以一个<CRLF>结束的邮件内容<br/><br/>应答<br/>接收SMTP对发送SMTP的通过传输信道发送的的对某一命令的（成功或不成功的）响应。应答的一般格式是应答码加一段文本。通常情况下，应答码供机器使用，而文本用于人类用户使用<br/><br/>邮件内容<br/>一系列的字符串，它们符合ARPA Internet文本信息格式标准的标准字符集<br/><br/>邮件内容结束标记<br/>标明邮件内容结束的特定字符<br/><br/>邮箱<br/>指定应该向何处发向用户的信件的地址（字符串）。它通常由用户名和主机名表示<br/><br/>命令<br/>由发送SMTP发送到接收SMTP的要求一个邮件服务操作的请求<br/><br/>域<br/>邮件系统中主机地址字符串的层次式表示<br/><br/>接收SMTP进程<br/>与发送SMTP进程一起工作的进程。它等待通过传输服务建立的连接。它接收发送SMTP发出的命令，给出应答并执行相应的操作<br/><br/>操作<br/>一个信息由一个接收者发送到另一个或多个接收者的一系列操作<br/>参考资料<br/>   [1]  ASCII<br/><br/>      ASCII, "USA Code for Information Interchange", United States of<br/>      America Standards Institute, X3.4, 1968.  Also in:  Feinler, E.<br/>      and J. Postel, eds., "ARPANET Protocol Handbook", NIC 7104, for<br/>      the Defense Communications Agency by SRI International, Menlo<br/>      Park, California, Revised January 1978.<br/><br/>   [2]  RFC 822<br/><br/>      Crocker, D., "Standard for the Format of ARPA Internet Text<br/>      Messages," RFC 822, Department of Electrical Engineering,<br/>      University of Delaware, August 1982.<br/><br/>   [3]  TCP<br/><br/>      Postel, J., ed., "Transmission Control Protocol - DARPA Internet<br/>      Program Protocol Specification", RFC 793, USC/Information Sciences<br/>      Institute, NTIS AD Number A111091, September 1981.  Also in:<br/>      Feinler, E. and J. Postel, eds., "Internet Protocol Transition<br/>      Workbook", SRI International, Menlo Park, California, March 1982.<br/><br/>   [4]  NCP<br/><br/>      McKenzie,A., "Host/Host Protocol for the ARPA Network", NIC 8246,<br/>      January 1972.  Also in:  Feinler, E. and J. Postel, eds., "ARPANET<br/>      Protocol Handbook", NIC 7104, for the Defense Communications<br/>      Agency by SRI International, Menlo Park, California, Revised<br/>      January 1978.<br/><br/>   [5]  Initial Connection Protocol<br/><br/>      Postel, J., "Official Initial Connection Protocol", NIC 7101,<br/>      11 June 1971.  Also in:  Feinler, E. and J. Postel, eds., "ARPANET<br/>      Protocol Handbook", NIC 7104, for the Defense Communications<br/>      Agency by SRI International, Menlo Park, California, Revised<br/>      January 1978.<br/><br/>   [6]  NITS<br/><br/>      PSS/SG3, "A Network Independent Transport Service", Study Group 3,<br/>      The Post Office PSS Users Group, February 1980.  Available from<br/>      the DCPU, National Physical Laboratory, Teddington, UK.<br/><br/>August 1982                                                      RFC 821<br/>Simple Mail Transfer Protocol                                           <br/><br/>   [7]  X.25<br/><br/>      CCITT, "Recommendation X.25 - Interface Between Data Terminal<br/>      Equipment (DTE) and Data Circuit-terminating Equipment (DCE) for<br/>      Terminals Operating in the Packet Mode on Public Data Networks,"<br/>      CCITT Orange Book, Vol. VIII.2, International Telephone and<br/>      Telegraph Consultative Committee, Geneva, 1976.<br/><br/><br/>RFC821  SIMPLE MAIL TRANSFER PROTOCOL                          RFC821 简单邮件传输协议（SMTP）<br/><br/>1<br/><br/><br/>1<br/>ＲＦＣ文档中文翻译计划<br/><br/><br/><br/><br/><br/><br/>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/196.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=196</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=196&amp;key=7d99d3c5</trackback:ping></item><item><title>如何做DNS反向解析 如何做IP反向记录(PTR)呢？</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/191.html</link><pubDate>Sat, 27 Oct 2007 14:17:03 +0800</pubDate><guid>http://blog.bigcomic.com/post/191.html</guid><description><![CDATA[<strong><span style="COLOR: #ff0000">如果不设置DNS反向解析将无法向sina等邮箱发送邮件而且发至yahoo，hotmail等的邮件虽然不会被退回但是可能会被直接送至垃圾邮件箱！</span></strong><br /><br />假设服务器IP是211.147.9.106 1) 首先您要知道这个IP的反向域名解析是由哪台DNS服务器负责的。<br />您可以用这个网页查询反向域名解析信息 <a target="_blank" href="http://www.dnsstuff.com/tools/ptr.ch?ip=211.147.9.106"><span style="COLOR: #800080">http://www.dnsstuff.com/tools/ptr.ch?ip=211.147.9.106</span></a><br /><br />（把这个ip地址换成你自己的ip地址之后直接粘贴至ie地址栏即可）看最后一段<br />Details: ns.cnc.ac.cn.(an authoritative nameserver for 147.211.in-addr.arpa.,<br />which is in charge of the reverse DNS for 211.147.9.106) says that there are no PTR records for 211.147.9.106.<br />To get reverse DNS set up for 211.147.9.106, you need to speak to your Internet provider.<br />You could also check with sun@cnnic.cn., who is in charge of the 147.211.in-addr.arpa. zone.<br /><br />大概意思是您需要跟ns.cnc.ac.cn联系，ns.cnc.ac.cn负责211.147.9.106的反向域名解析。 2) 然后您可以要求您的IP提供商，也就是您的主机托管商，如果你的企业用户有固定ＩＰ，你应该找电信。要他们跟ns.cnc.ac.cn联系，给您的这个IP加上反向域名解析记录，一般将这个IP反向解析成您的邮件服务器对应的mx记录。<br /><br /><br />PS:<br />什么叫反向解析呢。比如你用 <a target="_blank" href="mailto:xxx@31896.net">xxx@31896.net</a> 这个邮箱给我的邮箱 <a target="_blank" href="mailto:123@163.com">123@163.com</a> 发了一封信。 163邮件服务器接到这封信会查看这封信的信头文件，这封信的信头文件会显示这封信是由哪个IP地址发出来的。然后根据这个IP地址进行反向解析，如果反向解析到这个IP所对应的域名是31896.net。那么就接受这封邮件。如果反向解析发现这个IP没有对应到31896.net，那么就拒绝这封邮件。<p><span style="FONT-FAMILY: Arial">也许说到这里你还不是很明白。<br />你用过foxmail的特快专递没有？比如你在你的电脑中设置好foxmail的特快专递。注意，foxmail的特快专递是不需要设置smtp服务器的。因为这个时候是用你自己的电脑做smtp服务器。那么你用你自己的电脑，并以 <a target="_blank" href="mailto:xxx@31896.net">xxx@31896.net</a>的名义给我的邮箱 <a target="_blank" href="mailto:123@163.com">123@163.com</a> 发了一封信。很显然，这封信的信头显示的IP地址是你电脑的IP地址。那么163的邮件服务器反向解析这个IP。当然你的电脑的IP没有对应到 31896.net。那么163邮件服务器就认为这是一封垃圾邮件并拒收。<br /></span></p><br />]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/191.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=191</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=191&amp;key=827527d3</trackback:ping></item><item><title>RFC821 简单邮件传输协议（SMTP）</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/188.html</link><pubDate>Tue, 16 Oct 2007 09:28:59 +0800</pubDate><guid>http://blog.bigcomic.com/post/188.html</guid><description><![CDATA[Network Working Group                                          J. Postel<br/>Request for Comments: DRAFT                                          ISI<br/>Replaces: RFC 788, 780, 772                                  August 1982<br/><br/><br/>RFC821 简单邮件传输协议（SMTP）<br/>(RFC821  SIMPLE MAIL TRANSFER PROTOCOL)<br/><br/><br/>目录<br/>1. 介绍	2<br/>2. SMTP模型	3<br/>3. SMTP过程	4<br/>3.1. MAIL	4<br/>3.2. 转发	5<br/>3.3. 确认和扩展	6<br/>3.4. 发送信件(mailing)和获得信件(sending)	7<br/>3.5. 打开和关闭	7<br/>3.6. 转发	8<br/>3.7. 域	9<br/>3.8. 改变角色	9<br/>4. SMTP说明	9<br/>4.1. SMTP命令	9<br/>4.1.1. 命令语法	9<br/>4.1.2. COMMAND语法格式	13<br/>4.2. SMTP响应	15<br/>4.3. 命令和应答序列	16<br/>4.4. 状态图	17<br/>4.5. 详细内容	18<br/>4.5.1. 最小实现	18<br/>4.5.2. 透明性	19<br/>4.5.3. 大小	19<br/>附录 A TCP传输服务	19<br/>附录 B NCP传输服务	20<br/>附录 C NITS	20<br/>附录 D X.25传输服务	20<br/>附录 E 应答码构成方法	20<br/>附录 F 一些例子	22<br/>参考资料	36<br/><br/>  1. 介绍<br/>　　简单邮件传输协议（SMTP）的目标是可靠高效地传送邮件，它独立于传送子系统而且仅要求一条可以保证传送数据单元顺序的通道。附录A，B，C和D描述了不同传送服务下SMTP的使用。在名词表中还定义了本文档中使用的术语。<br/>　　SMTP的一个重要特点是它能够在传送中接力传送邮件，传送服务提供了进程间通信环境（IPCE），此环境可以包括一个网络，几个网络或一个网络的子网。理解到传送系统（或IPCE）不是一对一的是很重要的。进程可能直接和其它进程通过已知的IPCE通信。邮件是一个应用程序或进程间通信。邮件可以通过连接在不同IPCE上的进程跨网络进行邮件传送。更特别的是，邮件可以通过不同网络上的主机接力式传送。<br/>2. SMTP模型 <br/>　　SMTP设计基于以下通信模型：针对用户的邮件请求，发送SMTP建立与接收SMTP之间建立一个双向传送通道。接收SMTP可以是最终接收者也可以是中间传送者。SMTP命令由发送SMTP发出，由接收SMTP接收，而应答则反方面传送。<br/>一旦传送通道建立，SMTP发送者发送MAIL命令指明邮件发送者。如果SMTP接收者可以接收邮件则返回OK应答。SMTP发送者再发出RCPT命令确认邮件是否接收到。如果SMTP接收者接收，则返回OK应答；如果不能接收到，则发出拒绝接收应答（但不中止整个邮件操作），双方将如此重复多次。当接收者收到全部邮件后会接收到特别的序列，如果接收者成功处理了邮件，则返回OK应答。<br/>SMTP提供传送邮件的机制，如果接收方与发送方连接在同一个传送服务下时，邮件可以直接由发送方主机传送到接收方主机；或者，当两者不在同一个传送服务下时，通过中继SMTP服务器传送。为了能够对SMTP服务器提供中继能力，它必须拥有最终目的主机地址和邮箱名称。<br/>　　MAIL命令参数是回复路径，它指定邮件从何处来；而RCPT命令的参数是转发路径的，它指定邮件向何处去。向前路径是源路径，而回复路径是返回路径（它用于发生错误时返回邮件）。<br/>　　当同一个消息要发往不同的接收者时，SMTP遇到了向不同接收者发送同一份数据的复制品的问题，邮件命令和应答有一个比较奇怪的语法，应答也有一个数字代码。在下面，例子中可以看到哪些使用实际的命令和应答。完整的命令和应答在第四节。<br/>　　命令与应答对大小写不敏感，也就是说，命令和应答可以是大写，小写或两者的混合，但这一点对用户邮件名称却不一定是对的，因为有的主机对用户名大小写是敏感的。这样SMTP实现中就将用户邮箱名称保留成初始时的样子，主机名称对大小写不敏感。<br/>　　命令与应答由ASCII字母表组成，当传送服务提供8位字节传送通道，每7位字符正确传送，而最高位被填充为0。当指定一般的命令或应答格式后，参数会由一些类似于语言的字符串表示出来，如"<string>"或"<reverse-path>"，这里尖括号表示这是一种类似于语言的变量。<br/>3. SMTP过程 <br/>　　本节提供了SMTP中的一些过程。头一个说明的是基本发送过程（定义为发送操作）。下来描述向前传送邮件，确认邮箱名称和扩展邮件列表，发送到终端和打开关闭交换。在本节的最后是对中断，邮件域的说明。本节的例子只是一部分命令和应答的序列，完整的例子见附录F。<br/>3.1. MAIL<br/>　　在SMTP发送操作中有三步，操作由MAIL命令开始给出发送者标识。一系列或更多的RCPT命令紧跟其后，给出了接收者信息，然后是DATA命令列出发送的邮件内容，最后邮件内容指示符确认操作。<br/><br/>　　过程中的第一步是MAIL命令，< reverse-path >包括源邮箱。<br/><br/>　　MAIL <SP> FROM:<reverse-path> <CRLF><br/><br/>　　此命令告诉接收者新的发送操作已经开始，请复位所有状态表和缓冲区。它给出反向路径以进行错误信息返回。如果请求被接收，接收方返回一个250 OK应答。<reverse-path>中不止包括了邮箱，它包括了主机和源邮箱的反向路由，其中的第一个主机就是发送此命令的主机。<br/><br/>　　过程中的第二步是发送RCPT命令。<br/><br/>　　RCPT <SP> TO:<forward-path> <CRLF><br/><br/>　　此命令给出向前路径标识接收者，如果命令被接收，接收方返回一个250 OK应答，并存储向前路径。如果接收者未知，接收方会返回一个550 Failure应答。此过程可能会重复若干次。<br/>　　<forward-path>不仅包括邮件，它是主机和目的邮箱的路由表，在其中的第一个主机就是接收命令的主机。 过程中的第三步是发送DATA命令。<br/><br/>DATA <CRLF><br/><br/>　　如果命令被接收，接收方返回一个354 Intermediate应答，并认定以下的各行都是信件内容。当信件结尾收到并存储后，接收者发送一个250 OK应答。因为邮件是在传送通道上发送，因此必须指明邮件内容结尾，以便应答对话可以重新开始。SMTP通过在最后一行仅发送一个句号来表示邮件内容的结束，在接收方，一个对用户透明的过程将此符号过滤掉，以不影响正常的数据。<br/>　　注意：邮件内容包括如下提示：Date, Subject, To, Cc, From。<br/><br/>　　邮件内容指示符确认邮件操作并告知接收者可以存储和再发送数据了。如果此命令被接收，接收方返回一个250 OK应答。DATA命令仅在邮件操作未完成或源无效的情况下失败。<br/><br/>　　上面所述的过程是一个发送操作。这些命令只能以上面的顺序使用。下例表示了在一个发送操作中这些命令的使用。<br/>　　SMTP过程例子 此例是在Alpha.ARPA主机的Smith发送邮件给Beta.ARPA主机的Jones，Green和Brown的，这里假定主机Alpha与主机Beta直接相连。<br/><br/>　　S: MAIL FROM:<Smith@Alpha.ARPA><br/>　　R: 250 OK<br/>　　S: RCPT TO:<Jones@Beta.ARPA><br/>　　R: 250 OK<br/>　　S: RCPT TO:<Green@Beta.ARPA><br/>　　R: 550 No such user here<br/>　　S: RCPT TO:<Brown@Beta.ARPA><br/>　　R: 250 OK<br/>　　S: DATA<br/>　　R: 354 Start mail input; end with <CRLF>.<CRLF><br/>　　S: Blah blah blah...<br/>　　S: ...等等<br/>　　S: <CRLF>.<CRLF><br/>　　R: 250 OK<br/>　　此信被前两个人接收，而第三个人在此主机上没有邮箱。<br/>3.2. 转发 <br/>　　下面是一些<forward-path>中目的地址不正确的，但接收者知道正确的目的地址的例子。在这些例子中，下列应答之一应该允许发送方与获得正确地址。<br/><br/>　　251：用户不在本地；将向前发送到<forward-path>。<br/><br/>　　这个应答意味着，接收方SMTP知道用户的邮箱在另外的主机上，而且意味着将在未来使用正确的转向路径。请注意，主机或者用户，或者它们两者是不同的。接收方负责传送消息。<br/><br/>　　551 ：用户非本地，请尝试<forward-path><br/><br/>　　这个应答意味着接收SMTP知道用户的邮箱在另外的主机上，并意味着使用了正确的转发路径。注意请注意，主机或者用户，或者它们两者是不同的。接收方拒绝接收此用户的信件，发送者必须根据提供的信息重新发送或者向原发送者返回错误信息。 下例显示了这些响应的应用。<br/><br/>　　转发的例子<br/>　　S: RCPT TO:<Postel@USC-ISI.ARPA>　　R: 251 User not local; will forward to <Postel@USC-ISIF.ARPA>　　或者<br/>　　S: RCPT TO:<Paul@USC-ISIB.ARPA>　　R: 551 User not local; please try <Mockapetris@USC-ISIF.ARPA><br/>3.3. 确认和扩展<br/>　　SMTP提供了另外的确认用户名和扩展邮件列表的功能。这些功能由VREF和EXPN命令完成，它们都以字符串为参数。对于VREF命令，字符串参数指的是用户名，对此命令的响应要包括用户的命名和用户的邮箱。对于EXPN命令，字符串参数指的是邮件列表，对此命令的响应多于一个，它们要包括所有列表中用户的命名和他们的邮箱。<br/>　　“用户名”是一个多余的项目，它是故意被加上的。如果主机采用VREF命令和EXPN命令，最后本地邮箱必须提供用户名使它被主机确认。如果主机选择由另外的字符串作为用户名，也是允许的。<br/>　　在一些主机中，邮箱列表和一个邮箱的代名有一点不清楚，因为一般的数据结构可能包括两种类型的入口。如果要发出对邮件列表的确认，应该给出确定响应。在接收到这个消息后，主机将把邮件传送到列表上所有的地址上去，如果没有接收到确定响应，就会报告错误。例如，"550 That is a mail list, not a user name"。如果请求用于扩展一个用户名，可能通过返回包括一个名字的列表来形成确定响应，如果没有接收到确定响应，就会报告错误。（例如， "550 That is a user name, not a mailing list"）。<br/>　　在多个响应的情况下（通常是对于EXPN而言的），每个应答指定一个邮箱。在模糊请求的情况下，例如"VRFY Smith"，这里两个Smith的响应必须是"553 User ambiguous"。<br/><br/>　　确认用户名的情况如下例所示：例3：<br/>　　确认用户名<br/>　　S: VRFY Smith R: 250 Fred Smith <Smith@USC-ISIF.ARPA><br/>　　或者<br/>　　S: VRFY Smith<br/>　　R: 251 User not local; will forward to <Smith@USC-ISIQ.ARPA><br/>　　或者<br/>　　S: VRFY Jones<br/>　　R: 550 String does not match anything.<br/>　　或者<br/>　　S: VRFY Jones<br/>　　R: 551 User not local; please try <Jones@USC-ISIQ.ARPA><br/>　　或者<br/>　　S: VRFY Gourzenkyinplatz<br/>　　R: 553 User ambiguous.<br/><br/>　　邮箱列表要求多个响应的情况如下例所示：<br/>　　S: EXPN Example-People<br/>　　R: 250-Jon Postel <Postel@USC-ISIF.ARPA>　　R: 250-Fred Fonebone <Fonebone@USC-ISIQ.ARPA><br/>　　R: 250-Sam Q. Smith <SQSmith@USC-ISIQ.ARPA><br/>　　R: 250-Quincy Smith <@USC-ISIF.ARPA:Q-Smith@ISI-VAXA.ARPA><br/>　　R: 250-<joe@foo-unix.ARPA><br/>　　R: 250 <xyz@bar-unix.ARPA><br/>　　或者<br/>　　S: EXPN Executive-Washroom-List<br/>　　R: 550 Access Denied to You.<br/><br/>　　VERF和EXPN命令的字符串命令参数因为具体实现的不同而不能再加以限制了。在一些系统上，EXPN命令的参数可能是一个包含邮件列表的文件名，但是在Internet上有许多不同的文件结构。<br/>　　VRFY和EXPN命令在最小实现中并不包括，当它们实现时，它们也不要求被在传送间实现。　<br/>3.4. 发送信件(mailing)和获得信件(sending) <br/>　　SMTP的主要目的是将邮件发送到用户的邮箱中。由一些主机提供的类似的功能是把邮件送至用户的终端（如果用户正打开终端）。将邮件送到用户的邮箱中称为发送信件（mailing）；而送至用户终端则称之为获得信件（sending）。因为在一些主机上，这两者的实现十分类似，所以它们同时被放入了SMTP中。然而，获得信件命令在SMTP的最小实现中是没有的。用户应该具有控制向终端上写信息的能力。大部分主机允许用户接受或者拒绝类似的信息。<br/>　　下面三个命令被定义来支持获得信件。它们被用于邮件命令而不是MAIL命令，指示接收SMTP这种操作的特殊意义：<br/>　　SEND <SP> FROM:<reverse-path> <CRLF><br/>　　SEND命令要求邮件内容直接传送到用户终端。如果用户未打开终端（或者未接收终端信息），450响应将返回一个RCPT命令。如果信息被成功发送，此操作成功。　<br/>　　SOML <SP> FROM:<reverse-path> <CRLF>　<br/>　　Send或者MaiL命令要求将邮件内容直接发送到用户的终端上（如果用户在终端上）。如果用户不在终端上，邮件内容直接进入邮箱。如果邮件被发送到用户终端或者用户信箱，发送操作成功。　<br/>　　SAML <SP> FROM:<reverse-path> <CRLF><br/>　　Send和MaiL命令要求邮件内容直接发送到用户终端上（如果用户在终端上）。不管怎么样，信件都会进入信箱。如果信件进入信箱，发送操作成功。<br/>　　用于MAIL命令的响应和这些命令的响应相同。 　<br/>3.5. 打开和关闭 <br/>　　当打开传送通道时，要交换一些信息以确定双方的身份。以下的命令是用于打开和关闭的：<br/>　　HELO <SP> <domain> <CRLF><br/>　　QUIT <CRLF><br/>　　在HELLO命令中，主机自己发送命令，此命令可以被解释为：“你好，我是XX"。<br/><br/>　　打开联结的例子<br/>　　R: 220 BBN-UNIX.ARPA Simple Mail Transfer Service Ready<br/>　　S: HELO USC-ISIF.ARPA<br/>　　R: 250 BBN-UNIX.ARPA<br/><br/>　　关闭联结的例子<br/>　　S: QUIT<br/>　　R: 221 BBN-UNIX.ARPA Service closing transmission channel<br/>3.6. 转发<br/>　　转发路径可能是如下格式："@ONE,@TWO:JOE@THREE"，在这里，ONE，TWO和THREE是主机。这种格式用于强调地址和路径的区别。邮箱是绝对地址，路径是关于如何到达的信息。这两个概念不应该被混淆。<br/>　　概念上，转发路径的元素被移动到回复路径作为从一个SMTP服务器到另一个SMTP服务器的信息。回复路径是一个反向数据源路径，例如从当前信息的位置到发起者的位置。当一个SMTP服务器从转发路径中删除自己的标记并将它插入到回复路径中时，它必须使用它发送环境能够理解的名称来进行，以防它的名称在不同的环境中被理解为不同的名字。<br/>　　如果当SMTP接收到信息的转发路径的第一个元素不是此SMTP的标记时，此元素不从转发路径中删除，而被用来决定下一个应该发送到的SMTP服务器。在任何情况下，SMTP都将自己的标记加入反向路径中。<br/>　　使用源路径时，接收SMTP接收转发的邮件并发送到另一接收SMTP服务器上。接收服务器可以接受或拒绝转发本地用户的邮件。接收SMTP通过将它自己的标记从转发路径移至回复路径的开始处来改变命令参数。这时，接收SMTP变成了发送SMTP，也就建立了到下一个转发路径中SMTP的通道，然后，它向这个SMTP发送邮件。<br/>　　在回复路径上的头一个主机应是发送SMTP命令的主机，在转发路径上第一个主机应是接收SMTP命令的主机。<br/>　　注意：转发路径和回复路径出现在SMTP命令和应答中，但不一定要出现在信息中。也就是说，没有必须要这样的路径特别这种格式出现在信息头的"To:"，"From:"和"CC:"等域中。<br/>　　　如果SMTP服务器接受了转发任务，但后来它发现因为转发路径不正确或者其它原理无法发送邮件，它必须建立一"undeliverable mail"信号，将它此信号送到此信的发主者那里。<br/>　　此信号必须是从此主机的SMTP服务上发出的，当然了，此服务器不应该再报告出错信息的错误。一种阻止这种出错报告循环的情况是在信号的邮件命令的回复路径上置空。在传送此信息时，允许将回复路径也置为空。一个MAIL命令后的回复路径为空表现为如下形式：<br/>　　MAIL FROM:<><br/><br/>　　下例中显示了不可传送的邮件信息。此信息是对从HOSTW上的JOE发出的邮件经过在HOSTX需要经过HOSTZ到达HOSTY时出错的回应。我们看到的例子是在HOSTX和HOSTY之间发生的。<br/><br/>　　不可传送邮件信息的例子<br/>　　S: MAIL FROM:<><br/>　　R: 250 ok<br/>　　S: RCPT TO:<@HOSTX.ARPA:JOE@HOSTW.ARPA><br/>　　R: 250 ok<br/>　　S: DATA<br/>　　R: 354 send the mail data, end with .<br/>　　S: Date: 23 Oct 81 11:22:33<br/>　　S: From: SMTP@HOSTY.ARPA<br/>　　S: To: JOE@HOSTW.ARPA<br/>　　S: Subject: Mail System Problem<br/>　　S:<br/>　　S: Sorry JOE, your message to SAM@HOSTZ.ARPA lost.<br/>　　S: HOSTZ.ARPA said this:<br/>　　S: "550 No Such User"<br/>　　S: .<br/>　　R: 250 ok<br/>3.7. 域 <br/>　　域是最近被引入ARPA Internet邮件系统的。使用域可以使地址空间从一个平面的普通字符串主机名变成全局地址的一个层次结构。主机由一个域名取代，起始主机是由一系列元串组成，它们由逗号按最特殊到一般的顺序排列。<br/>　　例如，"USC-ISIF.ARPA"，"Fred.Cambridge.UK"和"PC7.LCS.MIT.ARPA"可能是主机-域标识符。<br/>　　无论域名在SMTP中如何使用，只有正式的名称才可以被使用，不可以使用假名或昵称。<br/>3.8. 改变角色<br/>　　TURN命令可以用来改变在传输信道上通信的程序的角色。如果程序A现在是发送SMTP，它发送TURN命令并接到OK应答（250）后，它就变为接收SMTP了。同理，程序B也可以从接收SMTP变为发送SMTP。若要拒绝改变角色，接收方可以发送502作为应答。<br/>　　注意：此命令是可选的。在使用TCP的传输信道时，一般不使用此命令。然而，当建立传输信道的代价比较大时，此命令很有用。例如，此命令可以支持一般公共交换电话系统作为传输信道。<br/>4. SMTP说明 <br/>4.1. SMTP命令 <br/>4.1.1. 命令语法 <br/>　　SMTP命令定义了邮件传输或由用户定义的系统功能。它的命令是由<CRLF>结束的字符串。而在带有参数的情况下，命令本身由<SP>和参数分开，如果未带参数可以直接和<CRLF>连接。邮箱的语法格式必须和接收站点的格式一致。下面讨论SMTP命令和应答。<br/>　　发送邮件操作涉及到不同的数据对象，它们由不同的参数相互连接。回复路径就是MAIL命令的参数，而转发路径则是RCPT命令的参数，邮件日期是DATA命令的参数。这些参数或者数据对象必须跟在命令后。这种模式也就要求有不同的缓冲区来存储这些对象，也就是说，有一个回复路径缓冲区，一个转发路径缓冲区，一个邮件内容缓冲区。特定的命令产生自己的缓冲区，或使一个或多个缓冲的内容被清除。<br/>　　HELLO (HELO)<br/>　　此命令用于向接收SMTP确认发送SMTP。参数域包括发送SMTP的主机名。接收SMTP通过连接确认命令来向发送SMTP确认接收SMTP。引命令和OK响应确认发送和接收SMTP进入了初始状态，也就是说，没有操作正在执行，所有状态表和缓冲区已经被子清除。<br/>　　MAIL (MAIL) <br/>　　此命令用于开始将邮件发送到一个多个邮箱中。参数域包括回复路径。返回路径中包括了可选的主机和发送者邮箱列表。当有主机列表时，它是一个回复路径源，它说明此邮箱是由在表中的主机一一传递发送（第一个主机是最后一个接收到此邮件的主机）过来的。此表也有作向发送者返回非传递信号的源路径。因为每个传递主机地址都被加在此表起始处，它就必须使用发送IPCE而不是接收IPCE（如果它们不是一个IPCE的话）清楚的名称。一些出错信息的回复路径可能就是空的。<br/>　　此命令清除回复路径缓冲区，转发路径缓冲区和邮件内容缓冲区，并且将此命令的回复路径信息插入到回复路径缓冲区中。<br/>　　RECIPIENT (RCPT)<br/>　　此命令用于确定邮件内容的唯一接收者；多个接收者将由多个此命令指定。转发路径中包括一个可选的主机和一个必须的目的邮箱。当出现主机列表时，这就是一个源路径，它指明邮件必须向列表中的上一个主机发送。如果接收SMTP未实现邮件的传递发送，就会返回如未知本地用户（550）的信息给用户。<br/>　　当邮件被传递发送时，传递主机必须将自己的名称由转发路径的开始处移至回复路径的结束处。当邮件最终到达目的地时，接收SMTP将以它的主机邮件格式自己的名称插入目标邮件中。例如，由传递主机A接收的带有如下参数的邮件时，<br/>　　FROM:<USERX@HOSTY.ARPA><br/>　　TO:<@HOSTA.ARPA,@HOSTB.ARPA:USERC@HOSTD.ARPA><br/>　　将会变成如下形式：<br/>　　FROM:<@HOSTA.ARPA:USERX@HOSTY.ARPA><br/>　　TO:<@HOSTB.ARPA:USERC@HOSTD.ARPA>.<br/>　　此命令导致它的转发路径参数加入转发路径缓冲区中。<br/>　　DATA (DATA)<br/>　　接收者将跟在命令后的行作为邮件内容。此命令导致此命令后的邮件内容加入邮件内容缓冲区。邮件内容可以包括所有128个ASCII码字符。邮件内容由只包括一个句号的行结束，也就是如下的字符序列："<CRLF>.<CRLF>"，它指示了邮件的结束。<br/>　　邮件内容的结束指示要求接收者现在就处理保存的邮件内容。此过程将回复路径缓冲区，转发路径缓冲区和邮件内容缓冲区的内容全部清空。如果操作成功，接收者必须返回OK应答；如果失败也必须返回失败应答。<br/>　　当接收SMTP收到一条信息时，无论是用作转发还是此邮件已经到达目的地，它都必须在邮件内容的开始处加上时间戳这一行，这一行指示了接收到邮件主机和发出此邮件主机的标识，以及接收到邮件内容的时间和日期。转发的信件将有多行这样的时间戳。当接收SMTP作最后一站的传送时，它将返回路径信息行插入邮件中。此行包括了发送命令中的<reverse-path>的信息。在这里，最后一站的传送的意思是邮件将被送到目的用户手中，但在一些情况下，邮件可能需要更进一步的加工并由另外的邮件系统传送。<br/>　　可能在返回路径中的邮箱与实际发送的邮件不一致，这个情况可能发生在需要传送一个特定的错误处理信箱而不是信件发送者那里。上面所述说明了，最后的邮件内容由一个返回路径行，和在其后的一个或多个时间戳行构成。这些行后面是邮件内容的头和体信息。<br/>　　当处理后面的邮件数据指示部分成功时就需要特定的说明。这种情况可能发生在发送SMTP发现当邮件需要传送给多个用户时，只能够成功地向其中的一部分发送信息这种情况下。在这种情况下，必须对DATA命令发送OK应答，而接收SMTP组织并发送一个"不可传递邮件"信息到信息的发送者。在此信息中或者发送一个不成功接收者的列表，或者每次发送一个不成接收者，而发送多次。所有不可传递邮件信息由MAIL命令发送。<br/>　　返回路径和接收时间戳例子<br/>　　Return-Path: <@GHI.ARPA,@DEF.ARPA,@ABC.ARPA:JOE@ABC.ARPA><br/>　　Received: from GHI.ARPA by JKL.ARPA ; 27 Oct 81 15:27:39 PST<br/>　　Received: from DEF.ARPA by GHI.ARPA ; 27 Oct 81 15:15:13 PST<br/>　　Received: from ABC.ARPA by DEF.ARPA ; 27 Oct 81 15:01:59 PST<br/>　　Date: 27 Oct 81 15:01:01 PST <br/>　　From: JOE@ABC.ARPA <br/>　　Subject: Improved Mailing System Installed <br/>　　To: SAM@JKL.ARPA <br/><br/>　　This is to inform you that ... <br/>　　SEND (SEND)<br/>　　此命令用于开始一个发送命令，将邮件发送到一个或多个终端上。参数域包括了一个回复路径，此命令如果成功就将邮件发送到终端上了。 <br/>　　回复路径包括一个可选的主机列表和发送者邮箱。当出现主机列表时，表示这是一个传送路径，邮件就是经过这个路径上的每个主机发送到这里的（列表上第一个主机是最后经手的主机）。此表用于返回非传递信号到发送者。因为每个传递主机地址都被加在此表起始处，它就必须使用发送IPCE而不是接收IPCE（如果它们不是一个IPCE的话）清楚的名称。一些出错信息的回复路径可能就是空的。<br/>　　此命令清除回复路径缓冲区，转发路径缓冲区和邮件内容缓冲区，并且将此命令的回复路径信息插入到回复路径缓冲区中。<br/>　　SEND OR MAIL (SOML)<br/>　　此命令用于开始一个邮件操作将邮件内容传送到一个或多个终端上，或者传送到邮箱中。对于每个接收者，如果接收者终端打开，邮件内容将被传送到接收者的终端上，否则就送到接收者的邮箱中。参数域包括回复路径，如果成功地将信息送到终端或邮箱中此命令成功。<br/>　　回复路径包括一个可选的主机列表和发送者邮箱。当出现主机列表时，表示这是一个传送路径，邮件就是经过这个路径上的每个主机发送到这里的（列表上第一个主机是最后经手的主机）。此表用于返回非传递信号到发送者。因为每个传递主机地址都被加在此表起始处，它就必须使用发送IPCE而不是接收IPCE（如果它们不是一个IPCE的话）清楚的名称。一些出错信息的回复路径可能就是空的。<br/>　　此命令清除回复路径缓冲区，转发路径缓冲区和邮件内容缓冲区，并且将此命令的回复路径信息插入到回复路径缓冲区中。<br/>　　SEND AND MAIL (SAML)<br/>　　此命令用于开始一个邮件操作将邮件内容传送到一个或多个终端上，并传送到邮箱中。如果接收者终端打开，邮件内容将被传送到接收者的终端上和接收者的邮箱中。参数域包括回复路径，如果成功地将信息送到邮箱中此命令成功。<br/>　　回复路径包括一个可选的主机列表和发送者邮箱。当出现主机列表时，表示这是一个传送路径，邮件就是经过这个路径上的每个主机发送到这里的（列表上第一个主机是最后经手的主机）。此表用于返回非传递信号到发送者。因为每个传递主机地址都被加在此表起始处，它就必须使用发送IPCE而不是接收IPCE（如果它们不是一个IPCE的话）清楚的名称。一些出错信息的回复路径可能就是空的。<br/>　　此命令清除回复路径缓冲区，转发路径缓冲区和邮件内容缓冲区，并且将此命令的回复路径信息插入到回复路径缓冲区中。<br/><br/>　　RESET (RSET)<br/>　　此命令指示当送邮件操作将被放弃。任何保存的发送者，接收者和邮件内容应该被抛弃，所有缓冲区和状态表应该被清除，接收方必须返回OK应答。<br/><br/>　　VERIFY (VRFY)<br/>　　此命令要求接收者确认参数是一个用户。如果这是（已经知道的）用户名，返回用户的全名和指定的邮箱。此命令对回复路径缓冲区，转发路径缓冲区和邮件内容缓冲区没有影响。<br/><br/>　　EXPAND (EXPN)<br/>　　此命令要求接收者确认参数指定了一个邮件发送列表，如果是一个邮件发送列表，就返回表中的成员。如果这是（已经知道的）用户名，返回用户的全名和指定的邮箱。此命令对回复路径缓冲区，转发路径缓冲区和邮件内容缓冲区没有影响。<br/><br/>　　HELP (HELP)<br/>　　此命令导致接收者向HELP命令的发送者发出帮助信息。此命令可以带参数，并返回特定的信息作为应答。此命令对回复路径缓冲区，转发路径缓冲区和邮件内容缓冲区没有影响。<br/><br/>　　NOOP (NOOP) <br/>　　此命令不影响任何参数和已经发出的命令。它只是说明没有任何操作而不是说明接收者发送了一个OK应答。此命令对回复路径缓冲区，转发路径缓冲区和邮件内容缓冲区没有影响。<br/><br/>　　QUIT (QUIT)<br/>　　此命令指示接收方必须发送OK应答然后关闭传送信道。接收方在接到QUIT命令并做出响应之前不应该关闭通信信道。发送方在发送QUIT命令和接收到响应之前也不应该关闭信道。即使出错，也不应该关闭信道。如果连接被提前关闭，接收方应该象接收到RSET命令一样，取消所有等待的操作，但不恢复原先已经做过的操作。而发送方应该象接收到暂时错误（4XX）一样假定命令和操作仍在支持之中。<br/><br/>　　TURN (TURN)<br/>　　此命令指定接收方要么发送OK应答并改变角色为发送SMTP，要么发送拒绝信息并保持自己的角色。如果程序A现在是发送SMTP，它发出TURN命令后接收到OK（250）应答，它就变成了接收SMTP。程序A就进入初始状态，好象通信信道刚打开一样，这时它发送220准备好服务信号。如果程序B现在是接收SMTP，它发出TURN命令后接收到OK（250）应答，它就变成了发送SMTP。程序A就进入初始状态，好象通信信道刚打开一样，这时它准备接收220准备好服务信号。<br/>若要拒绝改变角色，接收方可以发送502应答。<br/>　 对于这些命令的顺序有一定的限制。对话的第一个命令必须是HELLO命令，此命令在此后的会话中也可以使用。如果HELLO命令的参数不可接受，必须由返回一个501失败应答，同时接收到的SMTP必须保持在与刚才一致的状态下。 NOOP，HELP,EXPN和VRFY命令可以在会话的任何时候使用。MAIL，SEND，SOML或SAML命令开始一个邮件操作。一旦开始了以后就要发送RCPT和DATA命令。邮件操作可以由RSET命令终止。在一个会话中可以有一个或多个操作。<br/>　　如果在操作开始参数不可接受，必须返回501失败应答，同时接收到的SMTP必须保持在与刚才一致的状态下。如果操作中的命令顺序出错，必须返回503失败应答，同时接收到的SMTP必须保持在与刚才一致的状态下。<br/>会话的最后一个命令必须是QUIT命令。此命令在会话的其它时间不能使用。<br/>4.1.2. COMMAND语法格式<br/>　 命令是由命令码和其后的参数域组成的。命令码是四个字母组成的，不区别大小写。因为下面的命令的作用是相同的：<br/>　　MAIL Mail mail MaIl mAIl<br/>　　这对于引导任何参数值的标记也是适用的，如TO和to就是一样的。命令码和参数由一个或多个空格分开。然而在回复路径和转发路径中的参数是区别大小写的。特别是在一些主机上，"smith"和"Smith"就根本不是一个用户。<br/>参数域由不定长的字符串组成，它由<CRLF>结束，接收方在完全接收到此序列前不会采取任何行动。方括号代表可选的参数域。如果不选择的话，系统选择默认的设置。<br/>　　下面是SMTP命令： HELO <SP> <domain> <CRLF> MAIL <SP> FROM:<reverse-path> <CRLF><br/>RCPT <SP> TO:<forward-path> <CRLF><br/>DATA <CRLF><br/>RSET <CRLF><br/>SEND <SP> FROM:<reverse-path> <CRLF><br/>SOML <SP> FROM:<reverse-path> <CRLF><br/>SAML <SP> FROM:<reverse-path> <CRLF><br/>VRFY <SP> <string> <CRLF><br/>EXPN <SP> <string> <CRLF><br/>HELP [<SP> <string>] <CRLF><br/>NOOP <CRLF><br/>QUIT <CRLF><br/>TURN <CRLF><br/><br/>　　上面参数域的格式在下面给BNF的格式给出，其中的"..."代表对于一个域的一次或多次的重复。<br/><reverse-path> ::= <path><forward-path> ::= <path><path> ::= "<" [ <a-d-l> ":" ] <mailbox> ">"<br/><a-d-l> ::= <at-domain> | <at-domain> "," <a-d-l><br/><at-domain> ::= "@" <domain><br/><domain> ::= <element> | <element> "." <domain><br/><element> ::= <name> | "#" <number> | "[" <dotnum> "]"<br/><mailbox> ::= <local-part> "@" <domain><br/><local-part> ::= <dot-string> | <quoted-string><br/><name> ::= <a> <ldh-str> <let-dig><br/><ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str><br/><let-dig> ::= <a> | <d><br/><let-dig-hyp> ::= <a> | <d> | "-"<br/><dot-string> ::= <字符串> | <字符串> "." <dot-string><br/><字符串> ::= <字符> | <字符> <字符串><br/><quoted-string> ::= """ <qtext> """<br/><qtext> ::= "\" <x> | "\" <x> <qtext> | <q> | <q> <qtext><br/><字符> ::= <c> | "\" <x><br/><dotnum> ::= <snum> "." <snum> "." <snum> "." <snum><br/><number> ::= <d> | <d> <number><br/><CRLF> ::= <CR> <LF><br/><CR> ::= 回车符（ASCII码13） <LF> ::= （ASCII码10）<br/><SP> ::= 空格（ASCII码32） <snum> ::=由一个，两个或三个数字组成的介于0-255之间的数字<br/><a> ::= 所有A-Z的52个大小写英文字母<br/><c> ::= 128个ASCII字符，但不包括空格和特殊字符<br/><d> ::= 0-9数字<br/><q> ::=不包括<CR>，<LF>，"或\的128个ASCII字符<br/><x> ::=所有128个ASCII字符<br/><special> ::= "<" | ">" | "(" | ")" | "[" | "]" | "\" | "." | "," | ";" | ":" | "@" """ 或控制字符<br/>　　注意： "\"是一个转意字符，它表示在其后的字符代表另外的意义。例如"Joe\,Smith"用于表示单独一个由逗号分隔的用户名。主机通常由转化为地址的名称代表。注意：域的名称元素是正式的名称，不能够使用昵称或假名。<br/>有时候名称的转变机制可能不知道主机，这就造成了通信的阻塞。为了解决这个问题，可以采取两种方法：一种方法是：在"#"后加入一个十进制数表示主机地址；另一种方法是在其后加入32位的IP地址，IP地址的形式是由句号分隔的四个介于0-255之间的十进制数。时间戳行和返回路径行的格式通常由下面定义：<br/><return-path-line> ::= "Return-Path:" <SP><reverse-path><CRLF><br/><time-stamp-line> ::= "Received:" <SP> <stamp> <CRLF><br/><stamp> ::= <from-domain> <by-domain> <opt-info> ";" <daytime><br/><from-domain> ::= "FROM" <SP> <域> <SP><br/><by-domain> ::= "BY" <SP> <域> <SP><br/><opt-info> ::= [<via>] [<with>] [<id>] [<for>]<br/><via> ::= "VIA" <SP> <连接> <SP><br/><with> ::= "WITH" <SP> <协议> <SP><br/><id> ::= "ID" <SP> <字符串> <SP><br/><for> ::= "FOR" <SP> <路径> <SP><br/><连接> ::= 在网络信息中心注册的连接的标准名称<br/><协议> ::= 在网络中心注册的协议的名称<br/><daytime> ::= <SP> <日> <SP> <时间><br/><日期> ::= <日> <SP> <月> <SP> <年><br/><时间> ::= <小时> ":" <分> ":" <秒> <SP> <时区><br/><dd> ::= 由一个或两个数字组成的每月1-31日<br/><月> ::= "JAN" | "FEB" | "MAR" | "APR" | "MAY" | "JUN" | "JUL" | "AUG" | "SEP" | "OCT" | "NOV" | "DEC"<br/><年> ::= 由两位数字表示本世界的年代00-99<br/><小时> ::= 每天的24小时，由0到24<br/><分> ::= 每小时的分钟数0-59<br/><秒> ::= 每分钟的秒数0-59<br/><时区> ::= 全球标准时区<br/>返回路径例子<br/>Return-Path: <@CHARLIE.ARPA,@BAKER.ARPA:JOE@ABLE.ARPA><br/>时间戳行例子<br/>Received: FROM ABC.ARPA BY XYZ.ARPA ; 22 OCT 81 09:23:59 PDT<br/>Received: from ABC.ARPA by XYZ.ARPA via TELENET with X25<br/>id M12345 for Smith@PDQ.ARPA ; 22 OCT 81 09:23:59 PDT<br/>4.2. SMTP响应<br/>　　对SMTP命令的响应是多样的，它确定了在邮件传输过程中请求和处理的同步，也保证了发送SMTP知道接收SMTP的状态。每个命令必须有且只有一个响应。<br/>　　SMTP响应由三位数字组成，其后跟一些文本。数字帮助决定下一个应该进入的状态，而文本对人是有意义的。三位的响应已经包括了足够的信息，不用再阅读文本，文本可以直接抛弃或者传递给用户。特别的是，文本是与接收和环境相关的，所以每次接收到的文本可能不同。在附录E中可以看到全部的响应码。正规的情况下，响应由下面序列构成：三位的数字，<SP>，一行文本和一个<CRLF>，或者也可以是一个多行响应。只有EXPN和HELP命令可以导致多行应答，然而，对所有命令，多行响应都是允许的。<br/>4.2.1. REPLY CODES BY FUNCTION GROUPS 500 格式错误，命令不可识别（此错误也包括命令行过长）<br/>501 参数格式错误<br/>502 命令不可实现<br/>503 错误的命令序列<br/>504 命令参数不可实现<br/>211 系统状态或系统帮助响应<br/>214 帮助信息<br/>220 <domain> 服务就绪<br/>221 <domain> 服务关闭传输信道 <br/>421 <domain> 服务未就绪，关闭传输信道（当必须关闭时，此应答可以作为对任何命令的响应）<br/>250 要求的邮件操作完成<br/>251 用户非本地，将转发向<forward-path><br/>450 要求的邮件操作未完成，邮箱不可用（例如，邮箱忙）<br/>550 要求的邮件操作未完成，邮箱不可用（例如，邮箱未找到，或不可访问）<br/>451 放弃要求的操作；处理过程中出错<br/>551 用户非本地，请尝试<forward-path><br/>452 系统存储不足，要求的操作未执行<br/>552 过量的存储分配，要求的操作未执行<br/>553 邮箱名不可用，要求的操作未执行（例如邮箱格式错误）<br/>354 开始邮件输入，以<CRLF>.<CRLF>结束<br/>554 操作失败<br/>4.3. 命令和应答序列<br/>　　发送者和接收者之间的通信是一问一答的交替对话形式，由发送者控制。这样，发送发出一条命令，接收者发出一个响应。接收者在发送下一条指令前必须等应答。一个重要的应答是连接应答。在连接完成时，接收者通常会发送220"服务就绪"。发送者在继续发送指令前会等待此应答。注意：每个连接应答必须拥有服务主机的正式名称作为第一部分，其后跟响应码。例如：<br/>　　220 <SP> USC-ISIF.ARPA <SP> Service ready <CRLF><br/>　 下面列出了成功和失败应答，这些应答必须遵守严格的次序，接收者可以不理会应答中的文本，但是由数字指定的意义和操作和命令应答序列不能更改。命令响应序列： <br/>　　每个命令列出了它可能的应答。使用在可能应答前的前缀"P"表示预备的（未用在SMTP中），"I"表示中间的，"S"表示成功，"F"表示失败，"E"表示错误。如果STMP接收者必须关闭信道，可以对任何命令作出421（服务不可用，关闭传输信道）响应。此表基于下面要讲述的状态图：<br/>CONNECTION ESTABLISHMENT（建立连接）<br/>S: 220<br/>F: 421<br/>HELO<br/>S: 250<br/>E: 500, 501, 504, 421<br/>MAIL<br/>S: 250<br/>F: 552, 451, 452<br/>E: 500, 501, 421<br/>RCPT S: 250, 251 F: 550, 551, 552, 553, 450, 451, 452 E: 500, 501, 503, 421<br/>DATA<br/>I: 354 -> data -> S: 250<br/>F: 552, 554, 451, 452<br/>F: 451, 554<br/>E: 500, 501, 503, 421<br/>RSET<br/>S: 250<br/>E: 500, 501, 504, 421<br/>SEND<br/>S: 250<br/>F: 552, 451, 452<br/>E: 500, 501, 502, 421<br/>SOML<br/>S: 250<br/>F: 552, 451, 452<br/>E: 500, 501, 502, 421<br/>SAML<br/>S: 250<br/>F: 552, 451, 452<br/>E: 500, 501, 502, 421<br/>VRFY<br/>S: 250, 251<br/>F: 550, 551, 553<br/>E: 500, 501, 502, 504, 421<br/>EXPN<br/>S: 250<br/>F: 550<br/>E: 500, 501, 502, 504, 421<br/>HELP<br/>S: 211, 214<br/>E: 500, 501, 502, 504, 421<br/>NOOP<br/>S: 250<br/>E: 500, 421<br/>QUIT<br/>S: 221<br/>E: 500<br/>TURN<br/>S: 250<br/>F: 502<br/>E: 500, 503 <br/>4.4. 状态图<br/>　　下面状态图是一个简单的SMTP实现，每一组命令都有一个状态图。在图中，只使用了响应码的第一位数字作为响应的代表。命令组是对每个命令建立模式然后以结构模式将命令集中起来的。对于每个命令有三种可能的应答：成功（S），失败（F）和错误（E）。在状态中，我们使用B代表开始，使用W代表等待应答。<br/><br/><br/>　　　此状态图使用了如下命令：HELO, MAIL, RCPT, RSET, SEND, SOML, SAML, VRFY, EXPN, HELP, NOOP, QUIT, TURN.<br/>下面是对于DATA命令的更复杂的状态图：<br/><br/>　　注意：这里的邮件内容是多行的，接收者只能收到最后一行时才发出应答。<br/>4.5. 详细内容<br/>4.5.1. 最小实现<br/>　　为使SMTP能够工作，对于接收者来说，这是最少应该实现的命令：<br/>COMMANDS - HELO<br/>MAIL<br/>RCPT<br/>DATA<br/>RSET<br/>NOOP<br/>QUIT<br/>4.5.2. 透明性<br/>　　没有对数据透明性的保证，在发送类似"<CRLF>.<CRLF>"结束邮件内容时会发生错误。通常，用户不关心这个"非法"序列。若要所有用户能够透明地使用必须使用以下措施：<br/>1. 在发送邮件之间，发送SMTP必须检查邮件的每一行，如果是一个句号，就在行首再加一个句号。<br/>2. 当邮件被接收时，接收SMTP必须检查邮件的每一行，如果发现一行仅有一个句号，邮件就此结束，如果一行中有两个句号，那么这一行中就只应该有一个句号，而将第一个句号删除。<br/>　　发送的邮件内容可以包括所有128个ASCII字符。所有字符发送到收信者的邮箱，包括格式符号和其它控制字符。如果传输信道提供一个8位数据流，7位的ASCII码就可以在其中传送，而将最高位置为0。一些系统在接收和存储时需要对数据进行格式转换。对于使用不同于ASCII字符集的主机或不能以串的形式而只能以记录形式存储的主机更是如此，如果必须进行转换，必须能够再次转换回来，对于用于存储转发的主机更是如此。<br/>4.5.3. 大小<br/>　　一些对象需要最大和最小大小。也就是说，每个实现必须能够接收大于最小大小的对象，不能发送大于最大大小的对象。对于可能的最大大小，实现技术上并没有限制。<br/>用户 用户名的最大长度是64个字节。<br/>域 域的最大长度是64个字符<br/>路径 回复路径和转发路径的最大长度是256个字符<br/>命令行 命令行的最大长度，包括回车符为512个字符<br/>应答行 应答行的最大长度，包括回车符为512个字符<br/>文本行 文本行的最大长度，包括回车符和为透明性增加的字符不得超过1000个字符<br/>接收缓冲区 接收缓冲区最多可以容纳100个接收者<br/>如果出错，应答如下： <br/>500 行过长<br/>501 路径过多<br/>552 接收者过多<br/>552 邮件内容过多<br/>附录 A TCP传输服务 <br/>　　传输控制协议（TCP）在ARPA Internet中使用，并遵守网络协议的US DoD标准。SMTP传输信道连接建立在发送进程的端口U和接收进程的端口L上。一个单一的全双工信道用于传输。被指定用于此协议的服务端口为25，也就是说L=25。TCP连接支持传输8位字节，而SMTP只需要传输7位；这样，每个8位字符的最高位被置为0。<br/>附录 B NCP传输服务<br/>　　ARPANET主机-主机协议（由网络控制程序实现）也可以用于ARPANET。SMTP传输信道连接建立在发送进程的端口U和接收进程的端口L上；其后，根据初始连接协议（ICP）建立一对简单连接。这一对简单连接被用作传输信道。此协议被指定为连接套接字25，也就是说L=25。NCP连接支持传输8位字节，而SMTP只需要传输7位；这样，每个8位字符的最高位被置为0。<br/>附录 C NITS<br/>　　也可以使用网络独立转输服务。通过在NITS在发送进程和接收进程之间建立传输信道。发送进程执行CONNECT原语，然后等待接收ACCEPT原语。NITS连接支持传输8位字节，而SMTP只需要传输7位；这样，每个8位字符的最高位被置为0。<br/>附录 D X.25传输服务<br/>　　可以直接使用公共数据网络接收的X.25服务，然而，推荐在其上使用可靠的端到端的协议如TCP。<br/>附录 E 应答码构成方法<br/>　　三位的应答码每一位都有特定的意义。每一位应答表示是否是成功的，失败的或未完成的。通过这一位，不复杂的SMTP发送就可以决定下一步的操作，如果发送方希望大概了解究竟出了什么问题，它可以检测第二位，而第三位则保存了最后更完整的信息。也就是说，从第一位到第三位，接收方可以一步比一步精确地确定接收方的状态。对于第一位有五种可能的表示代表不同的意义：<br/><br/>　　1yz 部分完成应答<br/><br/>　　命令被接受，但是要求的操作被中止，原因在应答码中。发送方应该再次发送另一命令指明是否继续操作，或者放弃操作。<br/><br/>　　2yz 全部完成应答<br/><br/>　　要求的操作已经完成，可以开始另一个新的请求。<br/><br/>　　3yz 需要近一步信息的部分完成应答<br/><br/>　　命令被接受，但是要求的操作被中止，需要接收进一步的信息。发送方应该发送另一条命令指明进一步的信息。<br/><br/>　　4yz 暂时未完成应答<br/><br/>　　命令未被接受，要求的操作也未执行，但是发生错误的状态是暂时的，可以再一次请求操作。发送者应该返回命令序列的开始命令（如果有的话）。很难解释这个暂时的意义，特别对于两个不同的站点来说。区别应答是属于些类还是下一类的方法是：如果能够不加任何改变地重复的再一次发送命令，就是本类的，如果不是，就是下一类（5yz）的。<br/><br/>　　5yz 永久未完成应答<br/><br/>　　命令未被接受，要求的操作未完成。发送对命令的重复不起作用。即使一些出错条件已经改变，但是用户已经不希望重试，而希望在未来的某个时间再进行操作。<br/><br/>　　应答的第二位的意义有以下几类：<br/><br/>x0z 语法：此类型的应答是针对以下情况的：语法错误；符合语法但命令不存在功能；未完成或冗余的命令。<br/><br/>x1z 信息：此类型的应答是用于请求信息的，如状态或帮助信息。<br/><br/>x2z 连接：此类型的应答是关于传输信道的。<br/><br/>x3z 未使用。<br/><br/>x4z 未使用。<br/><br/>x5z 邮件系统：此类型的应答指明接收方邮件系统关于请求传送或其它操作的状态的。<br/><br/>　　第三位给出了更详细的说明。列出的应答表说明了这一点。文本应答是推荐使用的，而不是必须使用的，它的内容是可以根据不同情况而变化的。另一方面，应答码必须严格遵守本节的说明。接收方不应该因为稍稍的不同情况而自己创建新的代码而不使用已经定义的代码。例如，如NOOP命令的情况，如果成功执行它后，不用返回任何新的信息，只用返回250应答。当发送的命令要求一个未实现的站点指定操作时，应答应该是502。 应答文本可能多于一行；在此情况下，文本必须被标记，接收文本的一方才不致于少读入一行数据。这要求特定的格式说明多行应答。此格式是：每一行，除了最后一行外，都以应答码加一个"-"开始。而最后一行以应答码加空格<SP>开始。如下例：<br/><br/>123-First line<br/><br/>123-Second line<br/><br/>123-234 text beginning with numbers<br/><br/>123 The last line<br/><br/>　　通常情况下，接收的一方只用寻找应答码加空格的那一行就可以，而忽略前面行的内容。在特殊的情况下，发送方必须知道响应文本的内容，这时接收应答的一方可以通过当时的情况正确地决定是否需要知道文本的内容。 　<br/>附录 F 一些例子 <br/>本节提供了一些SMTP会话的完整例子。<br/><br/>典型的SMTP操作<br/><br/>此类显示邮件如何由在USC-ISIF和机上的Smith发送到BBN-UNIX主机上Jones，Green和Brown的。这里，我们假设USC-ISIF主机直接和BBN-UNIX主机联系。Jones和Brown接收邮件，而Green在BBN-UNIX上没有邮箱。<br/><br/>R: 220 BBN-UNIX.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO USC-ISIF.ARPA<br/><br/>R: 250 BBN-UNIX.ARPA<br/><br/>S: MAIL FROM:<Smith@USC-ISIF.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<Jones@BBN-UNIX.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<Green@BBN-UNIX.ARPA><br/><br/>R: 550 No such user here<br/><br/>S: RCPT TO:<Brown@BBN-UNIX.ARPA><br/><br/>R: 250 OK<br/><br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Blah blah blah...<br/><br/>S: ...etc. etc. etc.<br/><br/>S: .<br/><br/>R: 250 OK<br/><br/>　<br/><br/>S: QUIT<br/><br/>R: 221 BBN-UNIX.ARPA Service closing transmission channel<br/><br/>放弃SMTP操作 <br/><br/>R: 220 MIT-Multics.ARPA Simple Mail Transfer Service Ready <br/><br/>S: HELO ISI-VAXA.ARPA R: 250 MIT-Multics.ARPA <br/><br/>S: MAIL FROM:<Smith@ISI-VAXA.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<Jones@MIT-Multics.ARPA><br/><br/>R: 250 OK<br/>　<br/>S: RCPT TO:<Green@MIT-Multics.ARPA><br/><br/>R: 550 No such user here<br/><br/>S: RSET<br/><br/>R: 250 OK<br/><br/>S: QUIT<br/><br/>R: 221 MIT-Multics.ARPA Service closing transmission channel<br/><br/>转发邮件 <br/><br/>第一步：源主机到转发主机<br/><br/>R: 220 USC-ISIE.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO MIT-AI.ARPA<br/><br/>R: 250 USC-ISIE.ARPA<br/><br/>　<br/><br/>S: MAIL FROM:<JQP@MIT-AI.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<@USC-ISIE.ARPA:Jones@BBN-VAX.ARPA><br/><br/>R: 250 OK<br/><br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Date: 2 Nov 81 22:33:44<br/><br/>S: From: John Q. Public <JQP@MIT-AI.ARPA><br/><br/>S: Subject: The Next Meeting of the Board<br/><br/>S: To: Jones@BBN-Vax.ARPA<br/><br/>S:<br/><br/>S: Bill:<br/><br/>S: The next meeting of the board of directors will be<br/><br/>S: on Tuesday.<br/><br/>S: John.<br/><br/>S: .<br/><br/>R: 250 OK<br/><br/>S: QUIT<br/><br/>R: 221 USC-ISIE.ARPA Service closing transmission channel<br/><br/>第二步：转发主机到目的主机<br/><br/>R: 220 BBN-VAX.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO USC-ISIE.ARPA<br/><br/>R: 250 BBN-VAX.ARPA<br/><br/>S: MAIL FROM:<@USC-ISIE.ARPA:JQP@MIT-AI.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<Jones@BBN-VAX.ARPA><br/><br/>R: 250 OK<br/><br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Received: from MIT-AI.ARPA by USC-ISIE.ARPA ;<br/><br/>2 Nov 81 22:40:10 UT<br/><br/>S: Date: 2 Nov 81 22:33:44<br/><br/>S: From: John Q. Public <JQP@MIT-AI.ARPA><br/><br/>S: Subject: The Next Meeting of the Board<br/><br/>S: To: Jones@BBN-Vax.ARPA<br/><br/>S:<br/><br/>S: Bill:<br/><br/>S: The next meeting of the board of directors will be<br/><br/>S: on Tuesday.<br/><br/>S: John.<br/><br/>S: .<br/><br/>R: 250 OK<br/><br/>S: QUIT<br/><br/>R: 221 USC-ISIE.ARPA Service closing transmission channel<br/>确认和发送<br/><br/>R: 220 SU-SCORE.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO MIT-MC.ARPA<br/><br/>R: 250 SU-SCORE.ARPA<br/><br/>S: VRFY Crispin<br/><br/>R: 250 Mark Crispin <Admin.MRC@SU-SCORE.ARPA><br/><br/>S: SEND FROM:<EAK@MIT-MC.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<Admin.MRC@SU-SCORE.ARPA><br/><br/>R: 250 OK<br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Blah blah blah...<br/><br/>S: ...etc. etc. etc.<br/><br/>S: .<br/><br/>R: 250 OK<br/><br/>S: QUIT<br/><br/>R: 221 SU-SCORE.ARPA Service closing transmission channel<br/><br/>获得和发送邮件 首先确定用户名，然后尝试将邮件发送到用户终端，当它失败时，发送到用户邮箱。<br/><br/>R: 220 SU-SCORE.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO MIT-MC.ARPA<br/><br/>R: 250 SU-SCORE.ARPA<br/><br/>　<br/><br/>S: VRFY Crispin<br/><br/>R: 250 Mark Crispin <Admin.MRC@SU-SCORE.ARPA><br/><br/>S: SEND FROM:<EAK@MIT-MC.ARPA><br/><br/>R: 250 OK<br/>S: RCPT TO:<Admin.MRC@SU-SCORE.ARPA><br/><br/>R: 450 User not active now<br/><br/>S: RSET<br/><br/>R: 250 OK<br/><br/>S: MAIL FROM:<EAK@MIT-MC.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<Admin.MRC@SU-SCORE.ARPA><br/><br/>R: 250 OK<br/><br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Blah blah blah...<br/><br/>S: ...etc. etc. etc.<br/><br/>S: .<br/><br/>R: 250 OK<br/><br/>S: QUIT<br/><br/>R: 221 SU-SCORE.ARPA Service closing transmission channel<br/><br/>上述问题的更有效的作法 <br/><br/>R: 220 SU-SCORE.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO MIT-MC.ARPA<br/><br/>R: 250 SU-SCORE.ARPA<br/>S: VRFY Crispin<br/><br/>R: 250 Mark Crispin <Admin.MRC@SU-SCORE.ARPA><br/><br/>S: SOML FROM:<EAK@MIT-MC.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<Admin.MRC@SU-SCORE.ARPA><br/><br/>R: 250 User not active now, so will do mail.<br/><br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Blah blah blah...<br/><br/>S: ...etc. etc. etc.<br/><br/>S: .<br/><br/>R: 250 OK<br/><br/>S: QUIT<br/><br/>R: 221 SU-SCORE.ARPA Service closing transmission channel<br/><br/>　　邮件列表 首先，两个邮件列表中的每一个在不同主机的不同会话上扩展，然后，通过转发主机向列表上的用户发送邮件。<br/><br/>第一步：扩展第一个列表<br/><br/>R: 220 MIT-AI.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO SU-SCORE.ARPA<br/><br/>R: 250 MIT-AI.ARPA<br/><br/>　<br/><br/>S: EXPN Example-People<br/><br/>R: 250-<ABC@MIT-MC.ARPA><br/><br/>R: 250-Fred Fonebone <Fonebone@USC-ISIQ.ARPA><br/><br/>R: 250-Xenon Y. Zither <XYZ@MIT-AI.ARPA><br/><br/>R: 250-Quincy Smith <@USC-ISIF.ARPA:Q-Smith@ISI-VAXA.ARPA><br/><br/>R: 250-<joe@foo-unix.ARPA><br/><br/>R: 250 <xyz@bar-unix.ARPA><br/><br/>S: QUIT<br/><br/>R: 221 MIT-AI.ARPA Service closing transmission channel<br/>　<br/>第二步：扩展第二个列表 <br/><br/>R: 220 MIT-MC.ARPA Simple Mail Transfer Service Ready <br/><br/>S: HELO SU-SCORE.ARPA<br/><br/>R: 250 MIT-MC.ARPA<br/><br/>S: EXPN Interested-Parties<br/><br/>R: 250-Al Calico <ABC@MIT-MC.ARPA><br/><br/>R: 250-<XYZ@MIT-AI.ARPA><br/><br/>R: 250-Quincy Smith <@USC-ISIF.ARPA:Q-Smith@ISI-VAXA.ARPA><br/><br/>R: 250-<fred@BBN-UNIX.ARPA><br/><br/>R: 250 <xyz@bar-unix.ARPA><br/><br/>S: QUIT<br/><br/>R: 221 MIT-MC.ARPA Service closing transmission channel<br/><br/>　<br/><br/>第三步：通过转发主机向包括于两个列表中的所有用户发送邮件 <br/><br/>R: 220 USC-ISIE.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO SU-SCORE.ARPA<br/><br/>R: 250 USC-ISIE.ARPA<br/><br/>S: MAIL FROM:<Account.Person@SU-SCORE.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<@USC-ISIE.ARPA:ABC@MIT-MC.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<@USC-ISIE.ARPA:Fonebone@USC-ISIQA.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<@USC-ISIE.ARPA:XYZ@MIT-AI.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT<br/><br/>TO:<@USC-ISIE.ARPA,@USC-ISIF.ARPA:Q-Smith@ISI-VAXA.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<@USC-ISIE.ARPA:joe@FOO-UNIX.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<@USC-ISIE.ARPA:xyz@BAR-UNIX.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<@USC-ISIE.ARPA:fred@BBN-UNIX.ARPA><br/><br/>R: 250 OK<br/><br/>　<br/><br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Blah blah blah...<br/><br/>S: ...etc. etc. etc.<br/><br/>S: .<br/><br/>R: 250 OK<br/><br/>S: QUIT<br/><br/>R: 221 USC-ISIE.ARPA Service closing transmission channel<br/><br/>转发的情况<br/><br/>R: 220 USC-ISIF.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO LBL-UNIX.ARPA<br/><br/>R: 250 USC-ISIF.ARPA<br/><br/>S: MAIL FROM:<mo@LBL-UNIX.ARPA><br/><br/>R: 250 OK<br/>　<br/>S: RCPT TO:<fred@USC-ISIF.ARPA><br/><br/>R: 251 User not local; will forward to <Jones@USC-ISI.ARPA><br/><br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Blah blah blah...<br/><br/>S: ...etc. etc. etc.<br/><br/>S: .<br/><br/>R: 250 OK<br/>S: QUIT<br/><br/>R: 221 USC-ISIF.ARPA Service closing transmission channel<br/><br/>第一步：尝试第一台主机上的邮箱<br/><br/>R: 220 USC-ISIF.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO LBL-UNIX.ARPA<br/><br/>R: 250 USC-ISIF.ARPA<br/><br/>S: MAIL FROM:<mo@LBL-UNIX.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<fred@USC-ISIF.ARPA><br/><br/>R: 251 User not local; will forward to <Jones@USC-ISI.ARPA><br/>　<br/>S: RSET<br/><br/>R: 250 OK<br/>　<br/>S: QUIT<br/><br/>R: 221 USC-ISIF.ARPA Service closing transmission channel<br/><br/>第二步：尝试第二台主机上的邮箱<br/><br/>R: 220 USC-ISI.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO LBL-UNIX.ARPA<br/><br/>R: 250 USC-ISI.ARPA<br/><br/>S: MAIL FROM:<mo@LBL-UNIX.ARPA><br/><br/>R: 250 OK<br/>　<br/>S: RCPT TO:<Jones@USC-ISI.ARPA><br/><br/>R: OK<br/><br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Blah blah blah...<br/><br/>S: ...etc. etc. etc.<br/><br/>S: .<br/><br/>R: 250 OK<br/>　<br/>S: QUIT<br/><br/>R: 221 USC-ISI.ARPA Service closing transmission channel<br/><br/>许多接收者的情况<br/><br/>R: 220 BERKELEY.ARPA Simple Mail Transfer Service Ready<br/><br/>S: HELO USC-ISIF.ARPA<br/><br/>R: 250 BERKELEY.ARPA<br/>　<br/>S: MAIL FROM:<Postel@USC-ISIF.ARPA><br/>R: 250 OK<br/>　<br/>S: RCPT TO:<fabry@BERKELEY.ARPA><br/><br/>R: 250 OK<br/><br/>S: RCPT TO:<eric@BERKELEY.ARPA><br/><br/>R: 552 Recipient storage full, try again in another transaction<br/>　<br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Blah blah blah...<br/><br/>S: ...etc. etc. etc.<br/>S: .<br/><br/>R: 250 OK<br/><br/>　<br/><br/>S: MAIL FROM:<Postel@USC-ISIF.ARPA><br/>R: 250 OK<br/><br/>S: RCPT TO:<eric@BERKELEY.ARPA><br/><br/>R: 250 OK<br/><br/>S: DATA<br/><br/>R: 354 Start mail input; end with <CRLF>.<CRLF><br/><br/>S: Blah blah blah...<br/><br/>S: ...etc. etc. etc.<br/><br/>S: .<br/><br/>R: 250 OK<br/><br/>S: QUIT<br/><br/>R: 221 BERKELEY.ARPA Service closing transmission channel<br/><br/>名词表:<br/><br/><CRLF><br/>回车<br/><br/><SP><br/>空格<br/><br/>ASCII<br/>美国标准信息交换码<br/><br/>主机<br/>拥有SMTP进程或邮箱的网络计算机<br/><br/>发送SMTP进程<br/>与接收SMTP进程一起工作的进程。发送SMTP开始传输服务连接，它发出SMTP命令，接收应答，管理邮件的传送<br/><br/>用户<br/>希望获得邮件服务的人（或以人的名义出现的进程），还有就是邮件的接收者。<br/><br/>会话<br/>当传输信道打开时进行的一系列信息交换<br/><br/>传输服务<br/>可靠的面向流的数据通信服务。例如：NCP，TCP，NITS。<br/><br/>传输信道<br/>在发送SMTP和接收SMTP之间建立的全双工的用于交换命令，应答和邮件内容的信道<br/><br/>字符<br/>可显示字符串<br/><br/>行<br/>以一个<CRLF>结束的邮件内容<br/><br/>应答<br/>接收SMTP对发送SMTP的通过传输信道发送的的对某一命令的（成功或不成功的）响应。应答的一般格式是应答码加一段文本。通常情况下，应答码供机器使用，而文本用于人类用户使用<br/><br/>邮件内容<br/>一系列的字符串，它们符合ARPA Internet文本信息格式标准的标准字符集<br/><br/>邮件内容结束标记<br/>标明邮件内容结束的特定字符<br/><br/>邮箱<br/>指定应该向何处发向用户的信件的地址（字符串）。它通常由用户名和主机名表示<br/><br/>命令<br/>由发送SMTP发送到接收SMTP的要求一个邮件服务操作的请求<br/><br/>域<br/>邮件系统中主机地址字符串的层次式表示<br/><br/>接收SMTP进程<br/>与发送SMTP进程一起工作的进程。它等待通过传输服务建立的连接。它接收发送SMTP发出的命令，给出应答并执行相应的操作<br/><br/>操作<br/>一个信息由一个接收者发送到另一个或多个接收者的一系列操作<br/>参考资料<br/>   [1]  ASCII<br/><br/>      ASCII, "USA Code for Information Interchange", United States of<br/>      America Standards Institute, X3.4, 1968.  Also in:  Feinler, E.<br/>      and J. Postel, eds., "ARPANET Protocol Handbook", NIC 7104, for<br/>      the Defense Communications Agency by SRI International, Menlo<br/>      Park, California, Revised January 1978.<br/><br/>   [2]  RFC 822<br/><br/>      Crocker, D., "Standard for the Format of ARPA Internet Text<br/>      Messages," RFC 822, Department of Electrical Engineering,<br/>      University of Delaware, August 1982.<br/><br/>   [3]  TCP<br/><br/>      Postel, J., ed., "Transmission Control Protocol - DARPA Internet<br/>      Program Protocol Specification", RFC 793, USC/Information Sciences<br/>      Institute, NTIS AD Number A111091, September 1981.  Also in:<br/>      Feinler, E. and J. Postel, eds., "Internet Protocol Transition<br/>      Workbook", SRI International, Menlo Park, California, March 1982.<br/><br/>   [4]  NCP<br/><br/>      McKenzie,A., "Host/Host Protocol for the ARPA Network", NIC 8246,<br/>      January 1972.  Also in:  Feinler, E. and J. Postel, eds., "ARPANET<br/>      Protocol Handbook", NIC 7104, for the Defense Communications<br/>      Agency by SRI International, Menlo Park, California, Revised<br/>      January 1978.<br/><br/>   [5]  Initial Connection Protocol<br/><br/>      Postel, J., "Official Initial Connection Protocol", NIC 7101,<br/>      11 June 1971.  Also in:  Feinler, E. and J. Postel, eds., "ARPANET<br/>      Protocol Handbook", NIC 7104, for the Defense Communications<br/>      Agency by SRI International, Menlo Park, California, Revised<br/>      January 1978.<br/><br/>   [6]  NITS<br/><br/>      PSS/SG3, "A Network Independent Transport Service", Study Group 3,<br/>      The Post Office PSS Users Group, February 1980.  Available from<br/>      the DCPU, National Physical Laboratory, Teddington, UK.<br/><br/>August 1982                                                      RFC 821<br/>Simple Mail Transfer Protocol                                           <br/><br/>   [7]  X.25<br/><br/>      CCITT, "Recommendation X.25 - Interface Between Data Terminal<br/>      Equipment (DTE) and Data Circuit-terminating Equipment (DCE) for<br/>      Terminals Operating in the Packet Mode on Public Data Networks,"<br/>      CCITT Orange Book, Vol. VIII.2, International Telephone and<br/>      Telegraph Consultative Committee, Geneva, 1976.<br/><br/><br/>RFC821  SIMPLE MAIL TRANSFER PROTOCOL                          RFC821 简单邮件传输协议（SMTP）<br/><br/>1<br/><br/><br/>1<br/>ＲＦＣ文档中文翻译计划<br/><br/><br/><br/><br/><br/><br/><br/><br/>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/188.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=188</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=188&amp;key=c2722fbf</trackback:ping></item><item><title>Qmail系统的介绍和准备工作</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/185.html</link><pubDate>Mon, 15 Oct 2007 23:51:39 +0800</pubDate><guid>http://blog.bigcomic.com/post/185.html</guid><description><![CDATA[作者：peng<br />论坛ID：peng&nbsp; &nbsp;www.chinaunix.net <br />QQ: 螃蟹 16360544<br /><br />1.1目的。<br />本文的目的，是用自由软件在一个Linux平台上安装一套功能完整的邮件系统，和如何来管理他。这里我以qmail作为smtp服务器，vpopmail 做pop3服务器和实现虚拟域、用mysql数据库来进行用户验证，用qmailadmin来实现图形化的用户管理。用ezmlm来提供对邮件列表的支 持。使用igenus来提供一个友善的webmail界面。<br />1.2 qmail管理与维护章节<br />（一）Qmail系统的介绍和准备工作。<br />（二）qmail+vpopmail+mysql+qmailadmin+ezmlm+igenus的安装<br />（三）qmail的工作原理和配置文件的设置。<br />（四）ucspi-tcp的原理和设置。<br />（五）vpopmail和qmailadmin对用户的管理。<br />（六）qmail的日志分析和管理。<br />（七）ezmlm实现邮件列表的应用和管理。<br />（八）系统的备份和FAQ。<br />1.2&nbsp; &nbsp; &nbsp; &nbsp; 安装要求<br />1、&nbsp; &nbsp; &nbsp; &nbsp; 请在安装系统前，最好要多看几片他人写的文档。<br />2、&nbsp; &nbsp; &nbsp; &nbsp; 悉了所有Dan Bernstein（qmail的作者）发布的文档； 熟悉www.qmail.org（qmail官方站点）的相关资源，尽量理解Life With qmail。<br />3、&nbsp; &nbsp; &nbsp; &nbsp; 安装软件包前，仔细阅读各自的README AND INSTALL文件，这是最好的安装指南！<br /><br />1.3感谢<br />&nbsp; &nbsp; 感谢www.chinaunix.net的论坛网友locklzy、wxy、gadfly，尤其感谢gadfly在技术上给的执导和支持。<br /><br />1．4软件介绍<br />httpd-2.0.40.tar.g&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 提供web服务的server。<br />&nbsp; &nbsp; autorespond.tar.gz&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 实现e-mail自动回复功能。<br />ezmlm-0.53.tar.gz&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;实现qmail邮件列表功能。<br />ezmlm-idx-0.40.tar.gz&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ezmlm's的补丁程序，使ezmlm支持qmail。<br />&nbsp; &nbsp; qmail-1.03.tar.gz&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Qmail软件包<br />&nbsp; &nbsp; qmailadmin-0.80.tar.gz&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;qmail的web管理软件。<br />&nbsp; &nbsp; ucspi-tcp-0.88.tar.gz&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; tcpserver service 程序。<br />&nbsp; &nbsp; vpopmail-5.2.tar.gz&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;实现pop3服务和支持虚拟域。<br />&nbsp; &nbsp; qmail-smtpd.c&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;qmail的补丁程序，实现smtp认证功能。&nbsp; &nbsp; <br />&nbsp; &nbsp; php4-200303121030.tar.gz&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;实现apache对php的支持<br />igenus_2_20030311.tgz&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;实现webmail的软件包。<br />Qmail-setup.1.5.3.tar.gz&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;用其中的qmailadmin汉化部件。<br />以上软件，可以到各自的网站去获取：<br />http://www.apache.org/<br />http://cr.yp.to/qmail.html<br />&nbsp; &nbsp; http://www.qmail.org/<br />http://www.inter7.com/vpopmail/<br />http://cr.yp.to/ezmlm.html<br />&nbsp; &nbsp; http://www.ezmlm.org/<br />http://www.inter7.com/qmailadmin look for autoresponder link<br />http://www.igenus.org<br />http://down.rree.com/iceblood/qmail_setup-v1.5.3.tar.gz<br /><br />1.5实现的功能<br />1、&nbsp; &nbsp; &nbsp; &nbsp; Qmail帐号与系统帐号的分离。<br />2、&nbsp; &nbsp; &nbsp; &nbsp; SMTP服务的密码验证功能,能有效的防止别人利用自己的服务器发送匿名信。<br />3、&nbsp; &nbsp; &nbsp; &nbsp; 用vpopmail提供pop3服务。<br />4、&nbsp; &nbsp; &nbsp; &nbsp; 实现对虚拟域的支持。<br />5、&nbsp; &nbsp; &nbsp; &nbsp; 实现邮件帐号WEB管理方式。<br />2、Qmail邮件列表功能。<br />3、Qmail自动回复功能。<br />5、邮件的WEB使用方式，如：WEB发邮件，查看邮件。<br />6、支持qmail的管理脚本，安装后可以运行qmail start|stop|restart来管理qmail。<br />7、全面支持Mysql数据库，用户信息和邮件列表都通过mysql存储和验证。<br />8、实现了QmailAdmin和webmail的中文界面。<br /><br />1.6 系统设置<br />&nbsp;&nbsp;我用的是redhat8.0的系统，在一台康柏的pc server上作的。安装的时候，选择了custom模式。我安装系统的时候，就选择了安装mysql的所有的包。<br />1.7 apache<br />&nbsp; &nbsp;在安装系统时，我没有默认安装apache。我用源代码编译APACHE，是使它打开DSO模块。然后编译PHP，将SO文件安装到你的APACHE的模块目录里,这样也方便以后扩展功能。<br />1.8 sendmail<br />&nbsp;&nbsp;在这里，sendmail已没有任何意义了。本文就是想用qmail来替代unix系统传统上的sendmail。这里我们将要删除他：<br /># rpm &ndash;e &ndash;nodeps sendmail<br />1.9 系统分区建议<br />&nbsp; &nbsp;由于本系统的qmail采用了Maildir格式存储用户的邮件消息。造成大量小文件存在，数量庞大的小文件如果放在 /var 或 /home下，将造成系统性能下降。建议vpopmail单独使用另一块硬盘。还要注意/var/和/home的分区大小。因为/var/要产生大量的日 志文件和qmail队列，/home/下用户要保留用户的信件文件。所以规划好硬盘的分区，可以免除以后不必要的麻烦。其实大家可以使用逻辑卷管理磁盘， 这样可以动态的更改各分区的大小，是个不错的选择。Linux8安装的时候可以设置。<br /><br />1.10 dns server设置。<br />&nbsp; &nbsp;在这里我的域名假设是：&nbsp; &nbsp;&nbsp;&nbsp;chinaunix.net<br />&nbsp; &nbsp;qmail这台主机名是：&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;mail.chinaunix.net<br />&nbsp; &nbsp;qmail这台主机的ip地址是： 192.168.1.2<br />&nbsp; &nbsp;我的mail用户的格式是：&nbsp; &nbsp; peng@chinaunix.net<br />&nbsp; &nbsp;虚拟域名1是：&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; chinaunix.com<br />&nbsp; &nbsp;虚拟域名2是：&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; fanqiang.com<br />以上的域名，他们各自的解析主机所对应的zone文件设置是：<br />mail&nbsp; &nbsp; IN&nbsp;&nbsp;A&nbsp; &nbsp;192.168.1.2<br />@&nbsp; &nbsp;&nbsp; &nbsp;IN&nbsp;&nbsp;MX 10&nbsp;&nbsp;mail<br /><br />1.11 关于本文挡的声明<br />&nbsp; &nbsp;这份文档，是我参考了大量的网友的文章和书籍而写成的。自己经过反复安装和测试，均安装成功。但由于本人水平有限，文档难免有一些遗漏。如果你在安装的时候发现有什么地方有错误的话，请去www.chinaunix.net 的mail论坛讨论，我尽快回复的。<br />&nbsp; &nbsp;对于这片文档，网友可以任意转贴。但出于对作者的尊重，转贴时请注明作者姓名]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/185.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=185</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=185&amp;key=ee891742</trackback:ping></item><item><title>qmail的工作原理和配置文件的设置</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/184.html</link><pubDate>Mon, 15 Oct 2007 23:49:13 +0800</pubDate><guid>http://blog.bigcomic.com/post/184.html</guid><description><![CDATA[作者：peng<br />论坛ID：peng&nbsp; &nbsp;www.chinaunix.net <br />QQ: 螃蟹 16360544<br /><br />前言<br />&nbsp; &nbsp; 在这章里，我们主要是介绍qmail的工作原理和配置文件的设置。通过这一节，让我们<br />更好的分析问题和设施qmail。<br />3.1 qmail是什么？<br />qmail包是在unix系统上的一个邮件程序。qmail程序是由dan bernstein开发出来的<br />为标准的unix服务器提供邮件传输代理的(mail transfer agent,mta)功能的，用来替代sendmail。qmail因特网主页http://www.qmail.org。<br />3.2 qmail和相关的服务<br />qmail提供了mta功能，但是客户要能看到自己的信件，还需要其他协议和软件。两种<br />常见的远程用户取回他们消息的机制是邮政协议(post office protocal,pop3)和互交邮件访问协议(interactive mail access protocol,imap)。<br />综述：<br />qmail系统包括几个可执行程序、配置文件、qmail工具和环境变量，这些彼此互相影响，共同提供邮件服务。<br />3.3 qmail投递邮件进程流程<br /><img border="0" alt="" onmousewheel="return imgzoom(this);" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmouseover="if(this.width&gt;screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onload="if(this.width&gt;screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" src="http://www.majiandesk.com/imag/1013.jpg" /><br /><br />qmail系统中有9个核心程序，这里简单的介绍一下。qmail-smtpd负责接收来自远程主机的邮件消息并将它们传送给qmail-queue处 理。qmail-inject程序是用来接收本地产生的邮件消息并传送给qmail-queue程序。qmai-queue程序处理他们发来的邮件，移进 邮件队列以便发送。一旦消息被成功的放在邮件队列中，就调用qmail-send程序来处理他。qmail-send检查邮件队列中每一个消息状态，前一 次邮件请求失败的消息被识别，并决定它是临时失败还是永久的，临时失败会再次投递，永久失败将被送递到qmail-clean程序，被删除掉。也就是说， qmail-clean实用来清除永久失败的的邮件消息的。<br />qmail-send调用了qmail-lspawn 和qmail-rspawn程序。qmail-send判断邮件是发给谁的，发给本地的，就交给qmail-lspawn程序，再由qmail- local投送到本地邮件服务器。要是确定为远程主机，就调用qmail-rspawn程序，qmail-rspawn为每一个邮件消息的接受方决定目的 的邮件服务器，再调用qmail-remote程序发送。<br />2.2qmail的进程<br />qmail-send <br />splogger qmail<br />qmail-lspawn<br />qmaiil-rspawn<br />qmail-clean<br />qmail在任何时候都要求有五个程序在后台运行。这些核心的程序允许qmail扫描新邮件，并将他们发送到适当的目的地。&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <br /><br />3.4 qmail实用工具程序<br />除了以上五个qmail进程外，进程和本地用户在处理和传输消息的过程中，都还会用到几个其他的qmail实用工具程序。如下：<br />bouncesaying&nbsp; &nbsp;&nbsp; &nbsp; 允许用户将消息转发给程序或者程序不可用时反弹回信息<br />condredirect&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;允许用户将消息转发给程序，然后把消息转发到另一个地址<br />except&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 过去常用来修改一个调用程序的退出编码<br />forward&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;将消息转发给一个备用的邮件地址<br />maildir2mbox&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;将在maildir格式邮箱中的消息转换到一个标准的sendmail邮箱中<br />maildirwatch&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;产生一个maildir格式的邮箱<br />maildirwatch&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;监控一个用户的邮件目录并报告所有的新消息<br />preline&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;在将消息转发给相关程序前预处理这些消息<br />qbiff&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 当新消息到达后向用户终端显示器上写一个通知<br />qmail-clean&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 从qmail邮件队列中永远的移出无法到达的消息<br />qmail-inject&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 将新消息插入到qmail邮件队列中<br />qmail-local&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;向本地邮件系统上的用户投递消息<br />qmail-lspawn&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;由qmail-send调用以便向qmail-local程序转发消息<br />qmail-newmrh&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;用来从morercpthosts文件中创建qmail数据库<br />qmail-newn&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 从一个包含系统用户名和邮件名的ASCII文件表建立一个qmail用户文件 <br />qmail-pop3d&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 接受pop3连接以便让用户阅读他们的邮箱<br />qmail-popup&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 用来验证pop3连接中的用户ID和密码<br />qmail-pw2u&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;将UNIX系统的用户id和密码转换成qmail-newn能用的一个表结构<br />qmail-qmtpd&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 接受远程主机发来的qmtp连接请求<br />qmail-qread&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;产生一个显示当前qmail邮件队列里消息的报告 <br />qmail-qstat&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;产生一个报告来显示当前处在qmail投送状态下等待发送的消息数目<br />qmail-queue&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;将邮件消息排队等待投送<br />qmail-remote&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 将消息投送给远程邮件用户<br />qmail-rspawn&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 由qmail-send调用来向qmail-remote转发消息<br />qmail-send&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;尝试投送qmail邮件队列里的邮件消息<br />qmail-showctl&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 显示当前的qmail系统配置情况<br />qmail-smtpd&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;接收来自远程主机的smtp连接请求<br />qmail-start&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;初始化qmail的启动脚本<br />qmail-tcpok&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;用来清空qmail-remote中用到的tcp超时记录表<br />qmail-tcpto&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;显示当前的tcp超时记录表<br />qreceipt&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;用来会应对要求受到进行确认的消息<br />sendmail&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;用来将sendmail程序的功能复制到mta程序中<br />splogger&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;将消息插入系统登陆程序中<br />tcp-env&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 将网络连接的信息转换成unix环境变量<br /><br />每一个qmail实用工具程序都在正确的处理和投递邮件消息中扮演不同的脚色。其中有一些只能qmail内核程序调用，其他的就可以由qmail的系统管理员用来处理消息并得到统计信息。还有一些可以被单个普通邮件用户来制定自己的邮件消息处理。<br />3.5 qmail环境变量<br />除了控制文件之外，qmail程序还能使用unix环境变量来控制他们的动作。多数的控制文件的值都能被一个相应设定的环境变量重载。如果该环境变量没有 设定，就使用控制文件的值。qmail的环境变量是在qmail程序运行前就被设置好的。这是由一个包装程序完成的。常见的是tcpwrapper和 tcpserver。本文就是用的tcpserver。在以后的《（四）ucspi-tcp的原理和设置》内容中，再详细讨论。<br />3.6 qmail控制文件<br />这一部，对于管理好qmail，非常重要的。控制文件是qmail配置中的中心环节，它控制了qmail的操作性为。它位于 /var/qmail/control目录下。每一个文件包含一个值，这个值定义了相应的qmail可执行程序的变量。qmail控制文件是定义了 qmail参数的ASCII文本文件。大多数控制文件要求一个单一的文本值，该值可以在一行中输入。也有一些控制文件能包含多个值。在这种情况下，每一个 值被输入到单独的一行中，每一行以一个标准的UNIX换行符（LF）结尾。还有一个要重点注意，就是控制文件的权限问题，推荐root可读写，其他只读。<br />#chmod 644&nbsp;&nbsp;/var/qmail/control/* <br /><br />以下将逐一介绍个控制文件：<br />--------&nbsp;&nbsp;badmailfrom&nbsp; &nbsp;&nbsp;&nbsp;<br />这个控制文件实现拒收邮件功能的，每一个地址遵循前面说的规则，要单独一行。而且，不用重起qmail就能生效。&nbsp;&nbsp;<br />例如：<br />peng@96633.net&nbsp; &nbsp; -----限制一个特定的用户<br />@jp.yahoo.com&nbsp; &nbsp;&nbsp;&nbsp;-----限制一台远程主机上的所有主机上的所有用户<br />@sina.com&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----限制整个域中的邮件<br />------&nbsp;&nbsp;bouncefrom<br />&nbsp;&nbsp;用来定义用户名的，该用户名是出现在那些被退回给原始发件人的消息中，一般都是永久的投递失败消息。Bouncefrom默认值是MAILER-DAEMON,它通常是一个虚拟用户名，是一个真实用户的别名。你要是想给用户的退信消息中用另一个名字，可以用一下命令：<br /># echo postmaster &gt;; /var/qmail/control/bouncefrom&nbsp;&nbsp;---给改为postmaster,我习惯的。<br />-------&nbsp;&nbsp;bouncehost<br />&nbsp;&nbsp;制定了退信消息中的主机名，默认的值是me文件的主机名。<br />--------&nbsp;&nbsp;concurrencylocal<br />&nbsp;&nbsp;定义了qmail能够同时运行的本地投送进程数。对于大型的邮件主机，非常重要。他的默认参数是10。就是允许多达10个本地邮件投递进程同时运行。 这个控制文件的最大值是由qmail源代码中的conf-spawn变异参数设置的，这个编译参数默认值是120，他的最大值是255。<br />--------&nbsp; &nbsp;concurrencyremote<br />&nbsp;&nbsp;定义了qmail可以同时运行的远程投递进程数，默认值是20。它也是由conf-spawn设置的，默认值是120，最大可设255。但是要根据你的实际情况，因为运行进程要需要内存和硬盘的，设太大了小心你的服务器负载！<br />-------&nbsp; &nbsp;defaultdomain<br />&nbsp; &nbsp;默认域名，如果给本地的邮件用户发信，没有加上域名，qmail-inject会给他添加defaultdomain文件中的域名。如果设置了QMAILDEFAULTDOMAIN环境变量，他就会重载defaultdomain控制文件的值。<br />---------&nbsp;&nbsp;defaulthost<br />&nbsp;&nbsp;默认主机名，同一邮件服务器上，给本地用户发邮件，如果收信的用户地址没加域名，就会添加主机名。例如：邮件主机 mail.chinaunix.net,给本地用户peng@rchinaunix.net发邮件，from：peng ，那么qmail就会给这个消息扩充为peng@mail.chinaunix.net，qmail-send识别更容易了。通常，大家希望只看到域名 @chinaunix.net,不看到主机名@mail.chinaunix.net，因而qmail就只让你看到了域名。<br />------databytes<br />&nbsp;&nbsp;定义由qmail-smtpd接受到的邮件消息所允许的最大字节数，也就是发送和接受邮件的大小（本机上给本机用户出发和接受除外）。就是说，远程邮 件主机和你用outlook、foxmail等远程的mua工具发信，都受他的限制。默认值是0，表示不限制。无法理解的是，默认没有这个文件，一定要加 上。假想以下，有个电信的哥们给你使坏，在骨干网机房，写个定时任务，没事就给你发几个100m的信件，嘿嘿。。。<br /># echo 10000000 &gt;;/var/qmail/control/databyte&nbsp; &nbsp;---设置为10m，超过10m，将得到code 552，告知：其邮件大小超出了该邮件主机所能容忍的限度<br />----&nbsp;&nbsp;doublebouncehost<br />&nbsp;&nbsp;用来为那些经历了两次反弹后的消息指定主机名。默认是me文件的值<br />----&nbsp;&nbsp;doublebounceto<br />&nbsp;&nbsp;用来为那些经历了两次反弹后的消息指定用户名，默认是postmaster。<br />----&nbsp;&nbsp;envnoathost<br />&nbsp; &nbsp;是qmail-send用来为没有指定主机名的邮件接受方指定他的主机名的，默认是没有这个控制文件的，qmail-send使用me文件定义的<br />----&nbsp;&nbsp;helohost<br />&nbsp; &nbsp;指定在qmail-remote与远程邮件服务器的smtp会话中用到的主机名。如果helohost控制文件没有给出，qmail-remote使用me文件的值。<br />----&nbsp;&nbsp;idhost<br />&nbsp;&nbsp;指定了用来在消息中产生message-ID：头字段得主机名，默认qmail-inject用me文件的值。<br />----&nbsp;&nbsp;localiphost<br />&nbsp;&nbsp;用来为邮件消息指定本地地址的，内容是邮件主机的ip地址。但是它用在dns上就会有问题。建议不要设置。<br />----&nbsp;&nbsp;locals<br />&nbsp;&nbsp;指定邮件本地地址，不存在，qmail-send就假定me文件的值为邮件主机的唯一可用本地邮件主机。<br />----&nbsp;&nbsp;me<br />&nbsp;&nbsp;用来指定本地邮件服务器的主机名，最重要的控制文件，如果没有，qmail将不会运行。<br />me控制文件通常是靠运行qmail配置子目录下的config脚本文件来建立的，config脚本自动判断邮件服务器的dns域名，并产生一个适当的控 制文件（me ,locals,rcpthhosts）。如果某种原因你的邮件服务器无法连通dns服务器，可以手工运行configfast来指定邮件服务器主机名：<br /># /var/qmail/configure/config-fast mail.chinaunix.net<br /><br />----&nbsp;&nbsp;plusdomain<br />&nbsp;&nbsp;用来将一个域名指定成任何一个以一个加号（+）结尾的地址。缺省的情况下，出现在me文件的域名被添加到任何一个以加号结尾的邮件地址中。<br />----&nbsp;&nbsp;queuelifetime<br />&nbsp;&nbsp;用来指定一个消息在他被删除前，可以在邮件列表中保存的时间秒数。默认是604800，当投递失败的消息超过规定的时间，将被从邮件队列中删除。<br />----&nbsp;&nbsp;rcphosts<br />&nbsp;&nbsp;定义了qmail可以接收消息的主机和域名。 不过因为rcpthosts中的域名最好不要超过50行，多出的添加到morercpthosts中。<br />----&nbsp;&nbsp;morercpthosts<br />&nbsp;&nbsp;用来指定qmail将要为其接受消息的额外的主机和域名。<br />----&nbsp;&nbsp;smtpgreeting <br />用来指定SMTP连接的欢迎标志 ,默认是用me文件的主机名。<br />例如：smtpgreeting值为 welcome connect to out open relay mail server &ndash;mail.chinaunix.net<br />那么建立一个smtp连接的时候将会看到如下信息： <br />Trying 198.160.x.x... <br />Connected to mail.96633.net <br />Escape characteris ^]. <br />220 welcome connect to out open relay mail server &ndash;mail.chinaunix.net ESMTP<br />----&nbsp;&nbsp;smtproutes<br />&nbsp;&nbsp;用来指定能够被用来将邮件投送给特定目的地的静态smtp连接的。<br />smtprouter行格式如下：<br />host : relay<br />其中host可以是一个主机名或者域名，这个值将被重定向到有relay所定义的一个特定的邮件主机上。<br />举例：<br />beijing.chinaunix.net ：shanghai.chinaunix.net<br />chinaunix.net ：<br />：tianjin. chinaunix.net ：2000<br />第一行，定义了任何到beijing. chinaunix.net的消息重定向到shanghai. chinaunix.net<br />第二行，强制qmail对任何以chinaunix.net结尾的地址进行dns查询。<br />第三行，通过不指定第一个参数，任何不在前两行范围内的消息都会被转发到邮件服务器tianjin.96633.net。同时，还用2000端口替代标准的smtp tcp的25端口。这个技术常常用在通过一个防火墙连接到internet邮件中继中。<br />注意：smtproutes可定义许多特定的smtp路由。需要主机的是他的地址列表，qmail会按照smtproutes文件中出现的顺序，来处理这些地址。有时顺序不对，会引起邮件循环，切记！<br />----&nbsp;&nbsp;timeoutconnect<br />&nbsp;&nbsp;用来指定qmail-remote将要等待的一个时间秒数。也就是说等待远程smtp服务器接受本地的一个smtp请求响应的时间，默认是60秒。对于质量不好的网络，可以适当调节。<br />----&nbsp;&nbsp;timeoutremote<br />用来指定qmail-smtpd等待远程SMTP主机发送数据的时间线。默认的情况下，如果连接建立后1200秒内没有 接受到远程SMTP主机的任何信息，那么将关闭这个连接。<br />----&nbsp;&nbsp;timeoutsmtpd<br />&nbsp;&nbsp;用来指定qmail-smtpd等待远程smtp客户端连接的时间秒数。默认是1200，超过这个时间，连接取消。<br />----&nbsp;&nbsp;virtualdomains <br />让qmail接受本地邮件以外，还接受该文件中指定的域或者邮件地址，就是常说的虚拟域支持。<br />&nbsp;&nbsp;以上说的一些控制文件，qmail默认不是都有的，只有一些必须要得。根据你的mail不同的使用情况，自己选择来建立和设置。<br />3.6 系统别名<br />qmail的系统别名和sendmail不太一样，没有用一个大文件来包含所有的。而是建立了许多独立的别名文件。<br />在/var/qmail/alias中，格式如下：<br />。qmail-alias&nbsp; &nbsp;&nbsp;&nbsp;---alias是要建立的别名。<br />举例：我要给postmaster建立一个别名文件,使寄给postmaster的邮件都给peng<br />echo peng &gt;; /var/qmail/alias/.qmail-postmaster<br />3.7用户别名<br />除了系统文件，。Qmail还可以支持独立的用户系统配置文件。在用户的家目录中。<br />例如，在用户peng目录下，建立一个peng-sales的邮件列表，就可以建立 .qmail-sales文件，在文件中添加邮件地址，每个一行。这样发给peng-sales的邮件，就会给任何一个地址copy一份。<br />3.8改变MUA程序接口<br />qmail程序包含了一个可执行程序，该程序替代了unix标准的sendmail程序。你要想用qmail作为你的mail服务器，必须用qmail的sendmail包装程序替代现有的sendmail程序。<br /># mv /usr/sbin/sendmail /usr/sbin/sendmail.bak<br /># chmod 0 /usr/sbin/sendmail.bak<br /># ln &ndash;s /var/qmail/bin/sendmail /usr/sbin/sendmail<br />3.9建立qmailsmtp功能<br />&nbsp;&nbsp;传统上使用inetd程序来监听网络，但是缺点很多。本文中用ucspi-tcp包的tcpserver服务来代替它。参考了iceblood的qmail-setup.1.5.3的脚本文件，我是这样完成的：<br />1、&nbsp; &nbsp; &nbsp; &nbsp; 建立/etc/qmail目录，建立了smtp.sh and pop3.sh启动脚本<br />2、&nbsp; &nbsp; &nbsp; &nbsp; 建立了tcp.smtp 和tcp.smtp.cdb文件。<br />具体我是这样做的：<br />#echo &ldquo;/etc/qmail/start&rdquo; &gt;;&gt;; /etc/rc.d/rc.locad&nbsp; &nbsp;&nbsp;&nbsp;--- 开机执行/etc/qmail/start<br /># touch /etc/qmail/start&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; --- 建立执行文件<br /># touch /etc/qmail/smtp&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; --- 建立smtp脚本文件<br /># touch /etc/qmail/pop&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;--- 建立pop脚本文件<br /># touch /etc/qmail/tcp.smtp&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ---建立tcpserver的连接规则文件<br /># echo &quot;csh -cf '/var/qmail/rc &amp;'&quot;&gt;;/etc/qmail/start&nbsp; &nbsp; -- 开机启动qmail<br /># echo &quot;/etc/qmail/smtp.sh&quot;&gt;;&gt;;/etc/qmail/start&nbsp; &nbsp;&nbsp; &nbsp; -- 开机执行smtp.sh<br />smtp脚本内容：<br />/usr/local/bin/tcpserver -H -R &ndash;l chinaunix.net -t 1 -c 100 -v -p -x/etc/qmail/tcp.smtp.cdb <br />-u 502 -g 501 0 smtp /var/qmail/bin/qmail-smtpd /home/vpopmail/bin/vchkpw /bin/true | /var/qmail/bin/splogger &amp;<br />(注：502 and 501换成系统上的qmaild与nofiles的uid and gid的值。)<br />pop脚本内容：<br />/usr/local/bin/tcpserver -c 100 -v -l chinaunix.net -U -H -R 0 pop3 /var/qmail/bin/qmail-popup chinaunix.net /home/vpopmail/bin/vchkpw /var/qmail/bin/qmail-pop3d Maildir 2&gt;;&amp;1 <br />| /var/qmail/bin/splogger &amp;<br />tcp.smtp脚本内容<br />127.0.0.1:allow,RELAYCLIENT=&quot; &quot;<br />:allow<br /># /var/qmail/bin/tcprules /etc/qmail/tcp.smtp.cdb /etc/qmail/tcp.smtp.tmp &lt; /etc/qmail/tcp.smtp<br />以上配置，可以做到开机自动启动了。具体的详细参数配置，我们《（四）ucspi-tcp的原理和设置》部分再详细讨论。<br /><br />其实，/var/qmail/control/下的位置文件，有许多是不必要的。我的系统就用了一下几项：<br />databytes&nbsp; &nbsp;&nbsp; &nbsp;locals&nbsp; &nbsp;&nbsp; &nbsp; me&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; rcpthosts&nbsp; &nbsp;&nbsp; &nbsp; virtualdomains<br />defaultdomain&nbsp;&nbsp;locals.lock&nbsp;&nbsp;plusdomain&nbsp;&nbsp;rcpthosts.lock&nbsp;&nbsp;virtualdomains.lock<br />badmailfrom<br />只有databytes 、badmailfrom是我添加的，剩下都是系统默认有的。之所以介绍这么多，就是让大家根据自己的不同情况，自己设置。<br />3.10小结。<br />到这里，qmail这一部分就介绍完了。回顾一下：<br />我们明白了qmail的工作流程。<br />创建了基本的qmail控制文件。<br />在安装时，创建了必要的qmail系统别名。<br />决定了本地邮件的投递方式，安装时用的maildir。<br />创建了qmail启动脚本。<br />改变了mua的程序接口。<br />建立了qmail的smtp功能。<br />简单的讲了qmail配置文件.qmail。<br />从qmail这一部分来说，应该是可以了。<br /><br />关于本文挡的声明：<br />&nbsp; &nbsp;这份文档，是我参考了大量的网友的文章和书籍而写成的。自己经过反复安装和测试，均安装成功。但由于本人水平有限，文档难免有一些遗漏。如果你在安装的时候发现有什么地方有错误的话，请去www.chinaunix.net 的mail论坛讨论，我尽快回复的。<br />&nbsp; &nbsp;对于这片文档，网友可以任意转贴。但出于对作者的尊重，转贴时请注明作者姓名。]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/184.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=184</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=184&amp;key=0d1249d9</trackback:ping></item><item><title>ucspi-tcp的原理和设置</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/183.html</link><pubDate>Mon, 15 Oct 2007 23:30:20 +0800</pubDate><guid>http://blog.bigcomic.com/post/183.html</guid><description><![CDATA[作者：peng<br />论坛ID：peng&nbsp; &nbsp;www.chinaunix.net <br />QQ: 螃蟹 16360544<br /><br />Qmail的开发者dan Bernstein 开发了ucspi-tcp（UNIX客户-服务器程序端口）包来取代inetd程序。Ucspi格式定义了一种程序来交换数据的方法，主要体现出三个优点：<br />1、&nbsp; &nbsp; &nbsp; &nbsp; ucspi端口独立于底层的通讯介质。<br />2、&nbsp; &nbsp; &nbsp; &nbsp; ucspi允许shell脚本程序利用网络的互联。<br />3、&nbsp; &nbsp; &nbsp; &nbsp; ucspi程序建立了unix环境变量，这些变量定义了可以被程序和用户使用的网络信息。<br />Ucspi-tcp使用称为tool的程序在应用程序之间建立连接。有两种类型的ucspi tool&nbsp;&nbsp;---客户tool（tcpclient）和服务器tool（tcpserver）。<br /><br />Ucspi-tcp的tcpserver程序就是替代unix的inetd程序的，有如下优点：<br />1、他能够把来自服务器端的所有输入和输出都记到一个文件中。<br />2、他能提供访问控制特征，拒绝或者允许来自客户端的连接。<br />3、它包含了并发限制，防止使unix系统过载。<br /><br />Tcpserver程序通过使用管理员配置的一个hash规则库提供对访问的控制。<br />Tcpserver 命令行的格式是：<br />tcpserver&nbsp;&nbsp;options&nbsp;&nbsp;host&nbsp;&nbsp;port&nbsp;&nbsp;application<br />host和prot参数制定了将要运行应用程序的本地服务器的主机名和端口号。Host参数可以是localhos、主机ip address、或者是主机的完整域名。Port参数可以是一个数字或者是/etc/services文件中的一个tcp端口的名字，例如：smtp。 Application是连接建立后要传输给的应用程序。<br />Options参数定义了tcpserver程序的行为。有三种类型的选项：<br />常规选项------定义用于ucspi tool的选项。<br />连接选项-----处理到达的连接请求。<br />数据收集选项-----如何获得在传给应用程序的unix环境变量中使用信息。<br />Tcpserver连接选项（1）<br />---------------------------------------------------------------------------<br />选项&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 描述<br />-------------------------------------------------------------------------<br />-b n&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 允许n个连接请求的存储<br />-B banner&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;在连接建立后将banner写到网络连接上<br />-c n&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 不接受多于n个同时连接<br />-d&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;当主机相应较慢时延迟向远程主机发送数据<br />-D&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;从不延迟向远程主机发送数据<br />-g gid&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;当接受连接准备完成后改变活动组ID为gid<br />-l&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;打印本地端口号到stdout<br />-o&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;在连接的分组中不改变ip选项<br />-u uid&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;当接受连接准备完成后改变活动用户ID为uid<br />-O&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;删除ip选项为分组寻找路径<br />-U&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;相当于-g&nbsp;&nbsp;$GID&nbsp;&nbsp;&ndash;u&nbsp;&nbsp;UID<br />-x db&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 使用hash数据库db中的规则来接受或拒绝远程客户端的访问<br />-X&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;当由-x选项指定的数据库不存在时允许连接<br />-------------------------------------------------------------------<br />tcpserver程序可以使用的数据收集选项（2）<br />----------------------------------------------------------------<br />选项&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 描述<br />--------------------------------------------------------------------<br />-h&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;使用dns查找远程主机<br />-H&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;不使用dns查找远程主机名。你必须对端口53使用此选项<br />-l localhost&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;不使用dns查找本地服务器主机名，而使用localhost<br />-p&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 怀疑。使用反向dns 查找远程主机ip地址，将其与主机名相比较。如果不匹配，删除环境变量$tcpremotehost<br />-r&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;试图从远程主机获得$tcpremoteinfi (默认)<br />-R&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 不试图从远程主机获得$tcpremoteinfo数据。你必须为端口53和端口113使用这一选项<br />-t n&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;在n秒之后停止试图连接到$tcpremoteinfo数据。默认26<br />------------------------------------------------------------------------------<br />有几个unix环境变量tcpserver试图为其接受数据。这些环境变量帮助应用程序处理有关的网络间接信息。<br />Tcpserver的unix环境变量（3）<br />------------------------------------------------------------------------------<br />变量&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;描述<br />----------------------------------------------------------------------------<br />$PROTO&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;使用的协议（默认为TCP）<br />$TCPLOCALIP&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 本机的IP地址<br />$TCPLOCALPORT&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 本地TCP端口号<br />$TCPLOCALHOST&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 本地主机的DNS查询值<br />$TCPREMOTEIP&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;远程客户端的IP地址<br />$TCPREMOTEPROT&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;远程客户端的TCP端口号<br />$TCPREMOTEHOST&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;远程主机的DNS查询值<br />$TCPREMOTEINFO&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 远程客户端的用户名<br />------------------------------------------------------------------------------<br />当接受了一个远程客户端的连接，tcpserver就是图为应用程序提供环境变量，当他不能为一个特定的变量接受信息时，tcpserver不设置变量。<br />Tcprules程序<br />tcprules程序是创建可以限制与应用程序连接的规则。是手工创建规则，来制定接受和拒绝单个地址、多个ip地址、全部网络地址的访问。规则在一个文 本中创建，每行一条规则。文本建立后，使用cdb数据库格式将其转变成一个hash数据库。这使得tcpserver程序能够在远程客户向服务器请求连接 时动态处理规则。<br />规则以这样的格式创建：<br />address ：action,varible<br />address是和到达连接的值相匹配的。此参数的几种格式都是基于表（3）环境变量的，可以使用这些变量的组合来创建有效的地址。下面列出了tcpserver能识别的不同地址：<br />tcpserver规则的地址格式<br />-----------------------------------------------------------------------------<br />地址&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;示例<br />------------------------------------------------------------------------------<br />$tcpremoteinfo@tcpremteip&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; peng@[192.168.3.11]<br />$tcpremoteinfo@=$tcpremotehost&nbsp; &nbsp;&nbsp; &nbsp;peng@96633.net<br />$tcpremoteip&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;192.168.3.11<br />=$tcpremotehost&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;mail.chinaunix.net<br />部分$tcpremoteip&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;192.168<br />部分$tcpremotehost&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; chinaunix.net<br />空&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 任何地址<br />-------------------------------------------------------------------------------<br />action有两个选项：allow and deny。<br />除了动作以外，其他的以逗号分开的环境变量可以添加到action中，实现tcpserver在特定的远程客户连接请求时设置环境变量。这一特性可以实现选择转发等功能。<br />举几个例子吧：<br />---------------------------------------------------------------------------------<br />规则&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;描述<br />-------------------------------------------------------------------------------<br />192．168．0．1：deny&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;拒绝192.168.0.1的任何连接<br />192．168．3：allow&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 允许192.168.3.0上的客户任何连接<br />192．168．4．1-11：allow&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;允许192.168.4.1-192.168.44.11上的客户任何连接<br />：deny&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 拒绝任何连接<br />peng@chinaunix.net&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;允许peng@chinaunix.net 的连接<br />192．168．3：allow,RELAYCLIENT=&rdquo; &ldquo;&nbsp; &nbsp;接受192.168.3.0网络上的任何连接，设置环境变量RELAYCLIENT为空字符串。<br />-------------------------------------------------------------------------------------<br />本文建立SMTP转信规则[除本机外拒绝任何主机转发邮件，但不限制连接。] <br />#vi /etc/tcp.smtp<br />127.0.0.1:allow,RELAYCLIENT=&quot;&quot;<br />:allow<br />建立完文本文件，就用tcprules命令生成库文件，格式如下：<br />tcprules&nbsp;&nbsp;database&nbsp; &nbsp;tmpfile<br />本文中是这样的：<br /># /usr/local/bin/tcprules&nbsp;&nbsp;/etc/qmail/tcp.smtp.cdb&nbsp;&nbsp;/etc/qmail/tcp.smtp.tmp<br />这样，就生成了/etc/qmail/tcp.smtp.cdb文件了。tcp.smtp.cd表示适用于tcp协议，专用于smtp<br />协议，文件是cdb数据库格式。<br />下一步，就是告诉tcpserver如何应用它，本文的如下启动smtp服务：<br />/usr/local/bin/tcpserver -H -R -l 0 -t 1 -c 100 -v -p -x<br />/etc/qmail/tcp.smtp.cdb -u QMAILDUID -g NOFILESGID 0 smtp <br />/usr/local/qmail/bin/qmail-smtpd /home/vpopmail/bin/vchkpw /usr/bin/true <br />| /usr/local/qmail/bin/splogger &amp;<br /><br /># /usr/local/qmail/bin/tcpserver -c 100 -v -l $_DOMAIN -U -H -R 0 pop3 /usr/local/qmail/bin/qmail-popup domain /home/vpopmail/bin/vchkpw /usr/local/qmail/bin/qmail-pop3d Maildir 2&gt;;&amp;1 | /usr/local/qmail/bin/splogger &amp;<br /><br />相信看完以上的内容，应该能看懂本文的启动脚本了。当这里，ucspi-tcp的tcpserver就设制完成了。<br />关于本文挡的声明：<br />&nbsp; &nbsp;这份文档，是我参考了大量的网友的文章和书籍而写成的。自己经过反复安装和测试，均安装成功。但由于本人水平有限，文档难免有一些遗漏。如果你在安装的时候发现有什么地方有错误的话，请去www.chinaunix.net 的mail论坛讨论，我尽快回复的。<br />&nbsp; &nbsp;对于这片文档，网友可以任意转贴。但出于对作者的尊重，转贴时请注明作者姓名。]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/183.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=183</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=183&amp;key=0fe81d8f</trackback:ping></item><item><title>Menggunakan SMTP Auth (qmail-smtpd-auth) di vpopmail dan vmailmgr</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/181.html</link><pubDate>Mon, 15 Oct 2007 13:00:45 +0800</pubDate><guid>http://blog.bigcomic.com/post/181.html</guid><description><![CDATA[<h1>Menggunakan SMTP Auth (qmail-smtpd-auth) di vpopmail dan vmailmgr</h1><h2>Asfihani (asfik@cakraweb.com)</h2>21 Maret 2003<p><em>Jika Anda merasa apa yang saya tulis berikut ini berguna dan ingin membuat saya gembira, Anda bisa mengirimkan satu (atau lebih) CD dari daftar <a href="http://bebas.vlsm.org/v17/org/vlsm/asfik/wishlist/">wishlist</a> saya. Tentu saja, usaha Anda akan <strong>sangat</strong> saya hargai :-).</em></p><h3>1. Pendahuluan</h3><p>Salah satu tujuan dari penggunaan <em>smtp auth</em> adalah untuk mencatat (menge<em>log</em>) penggunaan SMTP dari <em>user-user</em> yang anda perbolehkan untuk me-<em>relay</em> SMTP. Hal ini diharapkan akan mengurangi penyalahgunaan SMTP, seperti misalnya mengirim SPAM, email bombing, ataupun mass mailing lainnya. Tujuan lainnya adalah sebagai seletif relay, misalnya jika kantor anda mempunyai sebuah dedicated server pada ISP A, namun anda juga berlangganan dialup ISP B dirumah, dan brengseknya ISP B ini SMTP nya menolak untuk meneruskan email jika <em>From :</em> nya tidak dari ISP B tersebut (misalnya ISP <strong>Telkomnet</strong> dan dengar-dengar sebentar lagi <strong>Indosat</strong>), maka selama ISP B masih bisa memforward port SMTP (25), anda bisa menggunakan server dedicated di ISP A sebagai SMTP sever untuk mengirim email walaupun anda dialup menggunakan ISP B. Tentu hal ini tidak efektif jika ISP anda masih bisa digunakan sebagai relay dan pasti bandwidthnya lebih besar dari server dedicated anda :)</p><p>Pada prinsipnya setiap seorang user akan mengirimkan email melalui sebuah server qmail dengan smtp auth, maka user yang bersangkutan akan diminta memasukkan username dan password terlebih dahulu, adapun database dari username dan password bisa menggunakan standar <strong>/etc/passwd</strong>atau menggunakan database virtual misalnya vpopmail/vmailmgr. Jadi selain server smtpnya (qmail) harus bisa mendukung authentikasi, maka client (MUA)nya juga harus support untuk mengirimkan proses authentikasi tersebut. Jika proses authentikasinya berhasil, maka MUA akan segera melakukan komunikasi SMTP seperti biasa, jika gagal maka proses pengiriman ditolak. Sederhana bukan?</p><p>Disini tidak akan saya jelaskan bagaimana menginstall cara qmail, vpopmail atau vmailmgr secara step by step, jadi akan saya gambarkan secara garis besarnya saja dan diasumsikan anda telah bisa menginstall qmail, vpopmail atau vmailmgr dengan benar.</p><h3>2. Mengepatch qmail dengan qmail-smtpd-auth</h3><p>Jika diserver anda sekarang sudah terdapat qmail yang berjalan dengan baik, jangan takut, karena waktu menginstall qmail dengan patch qmail-smtpd-auth ini hanya akan mengupdate binary file pada direktori <strong>/var/qmail/bin</strong> . Tapi, tentu saja tidak ada salahnya anda membackup direktori <strong>/var/qmail</strong> anda terlebih dahulu jika nantinya ada sesuatu yang tidak beres. Jangan lupa untuk mematikan servis qmail yang sedang aktif sebelum melakukan pengepatchan/penginstallan/pengupdatean (<em>qmailctl stop)</em>. Misalnya anda sudah download file <em>qmail-1.03.tar.gz</em>(serta telah membuat direktori dan user ataupun group yang dibutuhkan oleh qmail) dan file <em>qmail-smtpd-auth-0.31.tar.gz</em> yang bisa anda dapatkan dari <a href="http://members.elysium.pl/brush/qmail-smtpd-auth/dist/qmail-smtpd-auth-0.31.tar.gz">http://members.elysium.pl/brush/qmail-smtpd-auth/dist/qmail-smtpd-auth-0.31.tar.gz</a>, maka :</p><br /><pre xml:space="preserve">[root@wedus src]# tar -xzvf qmail-1.03.tar.gz [root@wedus src]# tar -xzvf qmail-smtpd-auth-0.31.tar.gz [root@wedus src]# cp qmail-smtpd-auth-0.31/{auth.patch,base64.c,base64.h,README.auth} qmail-1.03 [root@wedus src]# cd qmail-1.03</pre><br /><p>Jika anda ingin menambahkan patch yang lain, misalnya <em>qmailqueue-patch</em>dan/atau <em>qmail-quotas-patch</em>, maka lakukan sekarang. Namun, jika anda tidak ingin melakukannya anda bisa melalui 2 step berikut ini (file <em>qmailqueue-patch</em> dan <em>qmail-1.03-quotas-1.1.patch</em> misalnya sudah berada didirektori <strong>src/</strong>) :</p><br /><pre xml:space="preserve">[root@wedus qmail-1.03]# patch -p1 &lt; ../qmailqueue-patch [root@wedus qmail-1.03]# patch -p1 &lt; ../qmail-1.03-quotas-1.1.patch</pre><br /><p>Patch qmail dengan <em>qmail-smtpd-auth</em> :</p><br /><pre xml:space="preserve">[root@wedus qmail-1.03]# patch -p0 &lt; auth.patch</pre><br /><p>Install qmail seperti biasanya :</p><br /><pre xml:space="preserve">[root@wedus qmail-1.03]# make setup check</pre><br /><p>Jika sukses, seperti biasa file-file tersebut akan disalin kedirektori <strong>/var/qmail/bin</strong> . Kemudian edit file <strong>/etc/tcp.smtp</strong> anda untuk mengijinkan relay <strong>hanya</strong> dari localhost saja, karena nanti setelah qmail anda menggunakan <em>smtp auth</em>, user yang sukses authentikasi, akan langsung diberi hak untuk menggunakannya sebagai relay.</p><h3>3. Jika anda menggunakan vpopmail</h3><p>Install vpopmail seperti biasa, atau jika diserver anda sudah terdapat vpopmail maka anda harus mengganti kepemilikan file <strong>vchkpw</strong> menjadi user <em>root</em> dan membuatnya menjadi <em>SUID</em>, misalnya jika home direktori dari user vpopmail adalah <strong>/home/vpopmail</strong>, maka :</p><br /><pre xml:space="preserve">[root@wedus asfik]# chmod 4755 /home/vpopmail/bin/vchkpw [root@wedus asfik]# chown root.root /home/vpopmail/bin/vchkpw</pre><br /><p>Ubah file script supervise untuk qmail-smtpd (<strong>/service/qmail-smtpd/run</strong>) menjadi seperti ini :</p><br /><pre xml:space="preserve">#!/bin/sh PATH=$PATH:/usr/local/bin:/var/qmail/bin export PATH VPOPMAILUID=`id -u vpopmail` VPOPMAILGID=`id -g vpopmail` MAXSMTPD=30 exec /usr/local/bin/softlimit -m 4000000 \tcpserver -H -R -v -x /etc/tcp.smtp.cdb -c &quot;$MAXSMTPD&quot; -u &quot;$VPOPMAILUID&quot; -g &quot;$VPOPMAILGID&quot; \0 25 qmail-smtpd digimon.cs.perbanas.edu /home/vpopmail/bin/vchkpw /bin/true 2&gt;&amp;1</pre><br /><p>Ganti <strong>digimon.cs.perbanas.edu</strong> dengan host yang FQDN sesuai dengan host yang menjalankan qmail tersebut, kemudian perhatikan juga letak PATH dari file <strong>/home/vpopmail/bin/vchkpw</strong> dan file <strong>/bin/true</strong>, apakah berbeda dengan konfigurasi server anda. Kemudian perhatikan juga penulisan script anda, jika anda salah atau kurang teliti yang menyebabkan error, kemungkinan authentikasi akan ditolak atau yang lebih parah server anda bisa menjadi <strong>open relay</strong> dan ini sesuatu yang sangat tidak kita harapkan. Kemudian restart qmail anda (<em>qmailctl restart).</em></p><p>Untuk mengetestnya, anda bisa mencoba dari internal network anda dahulu. Anda harus meng-<em>encode</em> user dan password, caranya bikin suatu file script dengan menggunakan <em>perl</em> misalnya file <strong>base64.pl</strong> yang isinya seperti ini (Thanks to Bramsi Prenata) :</p><br /><pre xml:space="preserve">use MIME::Base64; print ('Username =&gt; '); print encode_base64('asfik@cs.perbanas.edu'); print ('Password =&gt; '); print encode_base64('motauajadeh'); </pre><br /><p>Ganti <strong>asfik@cs.perbanas.edu</strong> dan <strong>motauajadeh</strong> dengan username dan password yang sesuai, kemudian kita <em>encode</em> username dan password tersebut :</p><br /><pre xml:space="preserve">Username =&gt; YXNmaWtAdHJ1YmFncm91cC5jb20= Password =&gt; YQ== </pre><br /><p>Test telnet ke server tapi <strong>tanpa</strong> authentikasi :</p><br /><pre xml:space="preserve">[asfik@wedus asfik]$ telnet 10.126.10.13 25 Trying 10.126.10.13... Connected to 10.126.10.13. Escape character is '^]'. 220 digimon.cs.perbanas.edu ESMTP mail from : asfik@cs.perbanas.edu 250 ok rcpt to : asfik@its-sby.edu 553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1) quit 221 digimon.cs.perbanas.edu Connection closed by foreign host. </pre><br /><p>Anda harus mendapatkan pesan error, jika tidak berarti ada sesuatu yang tidak berese, kecualu anda memang merelay domain its-sby.edu :), sekarang kita coba dengan menggunakan authentikasi, ingat masukkan username dan password seperti diatas :</p><br /><pre xml:space="preserve">[asfik@wedus asfik]$ telnet 10.126.10.13 25 Trying 10.126.10.13... Connected to 10.126.10.13. Escape character is '^]'. 220 digimon.cs.perbanas.edu ESMTP auth login 334 VXNlcm5hbWU6 YXNmaWtAdHJ1YmFncm91cC5jb20= 334 UGFzc3dvcmQ6 YQ== 235 ok, go ahead (#2.0.0)mail from : asfik@cs.perbanas.edu 250 ok rcpt to : asfik@its-sby.edu 250 ok data 354 go ahead Subject : testing qmail-smtpd-auth . 250 ok 1048235800 qp 21936 quit 221 digimon.cs.perbanas.edu Connection closed by foreign host. </pre><br /><p>Jika sukses, langkah selanjutnya adalah mengkonfigurasi email client anda (MUA), lihat seksi 5.</p><h3>4. Jika anda menggunakan vmailmgr</h3><p>Install vmailmgr seperti biasa, atau jika diserver anda sudah terdapat vmailmgr maka anda harus mengganti mode file <strong>checkvpw</strong> menjadi <em>SUID</em> root, misalnya jika file tersebut terdapat pada direktori <strong>/usr/local/bin</strong>, maka :</p><br /><pre xml:space="preserve">[root@wedus src]# chmod 4755 /usr/local/bin/checkvpw </pre><br /><p>Ubah file script supervise untuk qmail-smtpd (<strong>/service/qmail-smtpd/run</strong>) menjadi seperti ini :</p><br /><pre xml:space="preserve">#!/bin/sh PATH=$PATH:/usr/local/bin:/var/qmail/bin export PATH QMAILDUID=`id -u qmaild` NOFILESGID=`id -g qmaild` MAXSMTPD=30 exec /usr/local/bin/softlimit -m 4000000 \tcpserver -H -R -v -x /etc/tcp.smtp.cdb -c &quot;$MAXSMTPD&quot; -u &quot;$QMAILDUID&quot; -g &quot;$NOFILESGID&quot; \0 25 qmail-smtpd digimon.cs.perbanas.edu /usr/local/bin/checkvpw /bin/true maildir 2&gt;&amp;1 </pre><br /><p>Ganti <strong>digimon.cs.perbanas.edu</strong> dengan host yang FQDN sesuai dengan host yang menjalankan qmail tersebut, kemudian perhatikan juga letak dari file <strong>/usr/local/bin/checkvpw</strong> dan file <strong>/bin/true</strong>, apakah berbeda dengan konfigurasi server anda. Kemudian perhatikan juga penulisan script anda, jika anda salah atau kurang teliti yang menyebabkan error, kemungkinan authentikasi akan ditolak atau yang lebih parah server anda bisa menjadi <strong>open relay</strong> dan ini sesuatu yang sangat tidak kita harapkan. Kemudian restart qmail anda (<em>qmailctl restart).</em></p><p>Untuk mengetestnya, anda bisa mencoba dari internal network anda dahulu. Anda harus meng-<em>encode</em> user dan password, caranya bikin suatu file script dengan menggunakan <em>perl</em> misalnya file <strong>base64.pl</strong> yang isinya seperti ini (Thanks to Bramsi Prenata) :</p><br /><pre xml:space="preserve">use MIME::Base64; print ('Username =&gt; '); print encode_base64('asfik@cs.perbanas.edu'); print ('Password =&gt; '); print encode_base64('motauajadeh'); </pre><br /><p>Ganti <strong>asfik@cs.perbanas.edu</strong> dan <strong>motauajadeh</strong> dengan username dan password yang sesuai, kemudian kita <em>encode</em> username dan password tersebut :</p><br /><pre xml:space="preserve">Username =&gt; YXNmaWtAdHJ1YmFncm91cC5jb20= Password =&gt; YQ== </pre><br /><p>Test telnet ke server tapi <strong>tanpa</strong> authentikasi :</p><br /><pre xml:space="preserve">[asfik@wedus asfik]$ telnet 10.126.10.13 25 Trying 10.126.10.13... Connected to 10.126.10.13. Escape character is '^]'. 220 digimon.cs.perbanas.edu ESMTP mail from : asfik@cs.perbanas.edu 250 ok rcpt to : asfik@its-sby.edu 553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1) quit 221 digimon.cs.perbanas.edu Connection closed by foreign host. </pre><br /><p>Anda harus mendapatkan pesan error, jika tidak berarti ada sesuatu yang tidak berese, kecualu anda memang merelay domain its-sby.edu :), sekarang kita coba dengan menggunakan authentikasi, ingat masukkan username dan password seperti diatas :</p><br /><pre xml:space="preserve">[asfik@wedus asfik]$ telnet 10.126.10.13 25 Trying 10.126.10.13... Connected to 10.126.10.13. Escape character is '^]'. 220 digimon.cs.perbanas.edu ESMTP auth login 334 VXNlcm5hbWU6 YXNmaWtAdHJ1YmFncm91cC5jb20= 334 UGFzc3dvcmQ6 YQ== 235 ok, go ahead (#2.0.0)mail from : asfik@cs.perbanas.edu 250 ok rcpt to : asfik@its-sby.edu 250 ok data 354 go ahead Subject : testing qmail-smtpd-auth . 250 ok 1048235800 qp 21936 quit 221 digimon.cs.perbanas.edu Connection closed by foreign host. </pre><br /><p>Jika sukses, langkah selanjutnya adalah mengkonfigurasi email client anda (MUA)</p><h3>5. Mengkonfigurasi MUA (Mail User Agent)</h3><p>Karena disini saya tidak pakai Microsoft Outlook? The Bat?ataupun Eudora? jangan tanyakan kepada saya bagaimana cara mengkonfigurasinya :) Yang akan saya uraikan disini adalah dengan menggunakan mutt, KMail, Ximian Evolution, dan Netscape?Communicator untuk Linux.</p><h3>mutt (1.4i)</h3><p>Jika anda pengguna mutt seperti saya (<strong>viva mutt!</strong>), anda harus menginstall <em>libesmtp</em> dan mengepatch mutt anda dengan patch libesmtp agar bisa melakukan authentikasi dengan server.</p><p>Download <em>libesmtp, mutt</em> dan <em>patch untuk mutt</em> :</p><br /><pre xml:space="preserve">[root@wedus source]# wget http://www.stafford.uklinux.net/libesmtp/libesmtp-1.0rc1.tar.bz2[root@wedus source]# wget ftp://ftp.mutt.org/mutt/mutt-1.4i.tar.gz [root@wedus source]# wget \http://www.deez.info/sengelha/projects/mutt/libesmtp/patch-1.4.sde.libesmtp.3 </pre><br /><p>Ekstrak :</p><br /><pre xml:space="preserve">[root@wedus source]# tar -jxvf libesmtp-1.0rc1.tar.bz2 [root@wedus source]# tar -xzvf mutt-1.4i.tar.gz </pre><br /><p>Install <em>libemstp</em> :</p><br /><pre xml:space="preserve">[root@wedus source]# cd libesmtp-1.0rc1 [root@wedus libesmtp-1.0rc1]# ./configure [root@wedus libesmtp-1.0rc1]# make [root@wedus libesmtp-1.0rc1]# make install </pre><br /><p>Install dan patch <em>mutt</em> :</p><br /><pre xml:space="preserve">[root@wedus libesmtp-1.0rc1]# cd ../mutt-1.4 [root@wedus mutt-1.4]# patch -p1 &lt; ../patch-1.4.sde.libesmtp.3 [root@wedus mutt-1.4]# ./configure --with-libesmtp [root@wedus mutt-1.4]# make [root@wedus mutt-1.4]# make install</pre><br /><p>Kemudian pada file konfigurasi mutt anda (<em>.muttrc</em>) anda bisa tambahkan misalnya seperti ini (ganti dengan konfigurasi yang sesuai ):</p><br /><pre xml:space="preserve">set smtp_host = digimon.cs.perbanas.eduset smtp_auth_username = asfik@cs.perbanas.eduset smtp_auth_password = motauajadeh</pre><br /><h3>KMail (1.4.1)</h3><p>Dari menu Setting -&gt; Configure KMail -&gt; Network -&gt; Sending, kemudian anda bisa memodifikasi atau menambah baru, misalnya klik Add -&gt; SMTP. Kemudian pada tab General -&gt; Name, Host, dan Port isikan sesuai dengan konfigurasi anda. Kemudian beri tanda cek pada &quot;Server requires authentication&quot;. Isikan Login dan Password yang sesuai, jika ingin menyimpannya berikan tanda cek pada &quot;Store SMTP password in configuration file&quot;. Kemudian yang terakhir dan paling penting pada tab Security , pilih None pada Encryption dan pilih LOGIN pada Authentication Method</p><h3>Ximian Evolution (1.0.3)</h3><p>Dari menu Tools -&gt; Mail Settings, pilih pada account anda untuk diedit atau klik Add untuk menambah, misalnya klik Edit, pilih pada tab Sending Mail. Kemdian pada Server Typte pilih SMTP, isikan host yang sesuai pada field Host. Beri tanda cek pada &quot;Server requires authentication&quot;, kemudian pilih Password pada Authentication Type. Terakhir, masukkan username anda pada field Username</p><h3>Netscape?Communicator (4.79)</h3><p>Dari menu Edit -&gt; Preferences -&gt; Mail and Newsgroup, pilih pada item Mail Servers. Pada kolom Outgoing mail server, isikan smtp host dan username yang sesuai pada Outgoing mail ( SMTP ) server dan pada Outgoing mail server username. Kemudian pilih &quot;If possible&quot; pada Use Secure Socket Layer (SSL) or TLS for outgoing message.</p><h3>6. Referensi</h3><br /><ul>    <li>qmail-smtpd-auth ( <a href="http://members.elysium.pl/brush/qmail-smtpd-auth/">http://members.elysium.pl/brush/qmail-smtpd-auth/</a>) </li></ul><br />]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/181.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=181</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=181&amp;key=1f13dd7c</trackback:ping></item><item><title>temp</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/180.html</link><pubDate>Sun, 14 Oct 2007 01:14:53 +0800</pubDate><guid>http://blog.bigcomic.com/post/180.html</guid><description><![CDATA[<p><a href="http://blog.bigcomic.com/upload/CIMG7274.JPG" rel="lightbox" title="CIMG7274.JPG"><img src="http://blog.bigcomic.com/upload/CIMG7274_tn.jpg" style="WIDTH: 500px; HEIGHT: 396px" title="CIMG7274.JPG" height="396" width="500" alt="CIMG7274.JPG" border="0" id="urn:zoundry:jid:CIMG7274.JPG"/></a></p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/180.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=180</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=180&amp;key=e2809c3d</trackback:ping></item><item><title>转:Qmail被黑</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/179.html</link><pubDate>Sat, 13 Oct 2007 00:18:07 +0800</pubDate><guid>http://blog.bigcomic.com/post/179.html</guid><description><![CDATA[<p>这次是被人偷了一个email账号，利用这个帐号乱发垃圾邮件，导致queue很快被塞满</p><p>一.现象：<br/>信件发送后，要等一天才能收到，或者根本收不到<br/>后来发现qmail的queue邮件队列巨长，主要是mess,info,remote三个目录<br/># du -d1 /usr/local/qmail/queue/<br/>2 /usr/local/qmail/queue/pid<br/>2 /usr/local/qmail/queue/intd<br/>2 /usr/local/qmail/queue/todo<br/>2 /usr/local/qmail/queue/bounce<br/>219660 /usr/local/qmail/queue/mess<br/>217660 /usr/local/qmail/queue/info<br/>64 /usr/local/qmail/queue/local<br/>217500 /usr/local/qmail/queue/remote<br/>4 /usr/local/qmail/queue/lock<br/>65560 /usr/local/qmail/queue/</p><p>二.找出入侵者：<br/>1.先看日志,注意带有"new msg","info msg"的信息行：<br/>#more /var/log/maillog<br/>...<br/>Apr 3 11:49:03 www qmail: 1049341743.532642 new msg 297872------记住这个队列号，查找这个队列号的邮件<br/>Apr 3 11:49:03 www qmail: 1049341743.533064 info msg 297872: bytes 893 from qp 16985 uid 1038<br/>Apr 3 11:49:03 www qmail: 1049341743.706272 new msg 298223<br/>Apr 3 11:49:03 www qmail: 1049341743.706691 info msg 298223: bytes 881 from qp 16986 uid 1038<br/>...<br/>2.然后看看那家伙是从哪里登录的：<br/>#find /usr/local/qmail/queue/ -name 297872<br/>/usr/local/qmail/queue/mess/22/297872<br/>/usr/local/qmail/queue/info/22/297872<br/>/usr/local/qmail/queue/remote/22/297872<br/>#more /usr/local/qmail/queue/mess/22/297872<br/>Received: from unknown (HELO smtp0251.mail.yahoo.com) (210.21.6.44)------这就是入侵者的ip地址<br/>From: "jenypher "<br/>X-Priority: 3<br/>To: sesto@altavista.net<br/>Subject: Enlarge your PENIS and improve your SEX Life!<br/>Mime-Version: 1.0<br/>Content-Type: text/html; charset=us-ascii<br/>Content-Transfer-Encoding: base64</p><p>三.找出被入侵的账号：<br/>通过lastauth文件，查找在210.21.6.44上登录的用户<br/>因为有很多用户，所以我写了个脚本来找被黑的用户<br/>#!/bin/sh<br/>#set -x</p><p>echo "" &gt; maillastauth.txt<br/>ls -d1 /home/vpopmail/domains/bsd.com/*/ &gt; mailusers.txt-----------输出所有用户的email路径</p><p>for MAILUSERS in `cat mailusers.txt`<br/>do<br/>more ${MAILUSERS}lastauth &gt;&gt; maillastauth.txt--------------------输出所有用户的lastauth文件<br/>echo $MAILUSERS &gt;&gt; maillastauth.txt------------------------------以及对应的用户<br/>done</p><p>more maillastauth.txt grep 210.21.6.44----------------------------输出在210.21.6.44上登录的用户</p><p>四.找到那个被黑的账号了，赶快修改密码，重新启动服务器（多此一举，呵呵~，只是自己感觉心里踏实一点）<br/>因为那家伙乱发邮件，所以postmaster收到很多MAILER-DAEMON@bsd.com的文件，删除这些垃圾<br/>/home/vpopmail/domains/bsd.com/postmaster/Maildir/cur/*<br/>/home/vpopmail/domains/bsd.com/postmaster/Maildir/new/*<br/>如果你的postmaster用户有其他的重要文件，可不要这么做<br/>还要看看你的queue邮件队列是不是在减少，如果还在继续增加，那完蛋了，估计系统账号都被黑了</p><p>五.昨天还干了点愚蠢的事情，因为看到queue里的文件很多，所以直接删除了queue队列里的文件，事实上这些文件是不能删除的<br/>否则就会出现类似"unable to stat mess/22/176892"这样的错误<br/>#more /var/log/maillog<br/>...<br/>Apr 1 18:07:41 www qmail: 1049191661.303612 warning: unable to stat mess/22/176892<br/>Apr 1 18:07:41 www qmail: 1049191661.303972 warning: unable to stat mess/16/346258<br/>Apr 1 18:07:41 www qmail: 1049191661.304059 warning: unable to stat mess/9/33773<br/>Apr 1 18:07:41 www qmail: 1049191661.304139 warning: unable to stat mess/2/190258<br/>...<br/>如果不小心，删除了queue队列里的文件，可以从qmail.org上下载qmail-fix来修复这个错误<br/>=================================================</p><p>、看队列中的邮件可以用<br/>#mailq</p><p>2、如果你要删除队列中的邮件，你可以看下面的提示，由于我这里没有环境，没法帮你确认可行性？？？</p><p>处理队列中的邮件：</p><p>A)如想在队列中的邮件马上传递，可以</p><p>#kill -HUP qmail-send</p><p>B)如果要删除队列中的邮件</p><p>1) 停止QMAIL<br/>2) find /var/qmail/queue/$i -type f -exec rm {} ;<br/>3) 重启QMAIL.<br/>队列中的邮件包含在以下目录中 /var/qmail/queue/{info,mess,remote,local}/hash/#number</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/179.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=179</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=179&amp;key=398eabab</trackback:ping></item><item><title>SMTP协议实例分析</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/176.html</link><pubDate>Sat, 29 Sep 2007 13:00:56 +0800</pubDate><guid>http://blog.bigcomic.com/post/176.html</guid><description><![CDATA[<p><strong>前言</strong></p><p>公司要求追踪EMAIL的到达情况，看客户是否收到信还是被某个路由拦截。打算采用Packet级跟踪。因此抓包分析,看有没可能性完成任务。</p><p><strong>环境</strong></p><p>客户端 windows2003 outlook2003</p><p>SMTP服务器 redhat 9 qmail</p><p><strong>涉及的软件和命令</strong></p><p>tcpdump 和 wireshark 0.99.5</p><p><strong>操作过程</strong></p><p>分析全程使用服务器上的网卡监视，用tcpdump -w smtp_packet tcp prot 25将smtp端口的数据存入smtp_packet文件，然后用wireshark分析。</p><p>发信人: <a href="mailto:systemadmin@xxxxxxx.com">systemadmin@xxxxxxx.com</a><br />收信人: <a href="mailto:pencat@bigcomic.com">pencat@bigcomic.com</a><br />主题: test<br />内容: test</p><p>本地IP: 192.168.2.180<br />SMTP IP: 192.168.2.5<br /><br /><a title="smtp_tcp_01.jpg" rel="lightbox" href="http://blog.bigcomic.com/upload/smtp_tcp_01.jpg"><img id="urn:zoundry:jid:smtp_tcp_01.jpg" title="smtp_tcp_01.jpg" style="WIDTH: 600px; HEIGHT: 517px" height="517" alt="smtp_tcp_01.jpg" width="600" border="0" src="http://blog.bigcomic.com/upload/smtp_tcp_01_tn.jpg" /></a></p><p>385、386、387 是TCP协议的三次握手，成功之后开始通信，下面是通信流向。</p><p><code>SENDER SMTP<br />220 xxxx.com ESMTP\r\n<br />&lt;--------------------------------------------------<br />EHLO tc4200\r\n<br />--------------------------------------------------><br />250-xxxx.com\r\n<br />250-PIPELINING\r\n<br />250<br />&lt;--------------------------------------------------<br />MAIL FROM: &lt;<a href="mailto:systemadmin@xxxxxxx.comm">systemadmin@xxxx.com</a>><br />--------------------------------------------------><br />250 ok\r\n<br />&lt;--------------------------------------------------<br />RCPT TO: &lt;<a href="mailto:pencat@bigcomic.com%3E/r/n">pencat@bigcomic.com>\r\n</a><br />--------------------------------------------------><br />250 ok\r\n<br />&lt;--------------------------------------------------<br />DATA\r\n<br />--------------------------------------------------><br />354 go ahead\r\n<br />&lt;--------------------------------------------------<br />Message Body<br />--------------------------------------------------><br />EOM:<br />--------------------------------------------------><br />250 ok 1191037138 qp 31636\r\n<br />&lt;--------------------------------------------------<br />Command: QUIT\r\n<br />--------------------------------------------------></code></p><p>通过分析，可以得出结论：采用Packet级的跟踪是无法实现完全跟踪，因为source与destination之间的路由是不透明的, 无法知道在哪个路由除了问题。只能从对方的MAIL SERVER得到一些基本信息，对跟踪毫无帮助，只能另想途径。</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/176.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=176</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=176&amp;key=2553c672</trackback:ping></item><item><title>windows2003下用命令行拨号</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/174.html</link><pubDate>Mon, 24 Sep 2007 14:44:18 +0800</pubDate><guid>http://blog.bigcomic.com/post/174.html</guid><description><![CDATA[<p>需求: 公司在美国有个VPN服务器, 分公司要连上去SAHRE资源.&nbsp;&nbsp; </p><p>方案: 在分公司架设一台VPN代理服务器,&nbsp;内网用户通过这个代理使用VPN.&nbsp; 为了让代理机器开机自动连接VPN&nbsp; 用DOS SHELL 做了个批处理,&nbsp; 在计划任务中运行. </p><p>用到的命令是rasdial</p><p>用法:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rasdial entryname [username [password|*]] [/DOMAIN:domain]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [/PHONE:phonenumber] [/CALLBACK:callbacknumber]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [/PHONEBOOK:phonebookfile] [/PREFIXSUFFIX]</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rasdial [entryname] /DISCONNECT</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rasdial</p><p>批处理文件:</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @echo off<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rasdial 连接名称 用户名 密码</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/174.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=174</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=174&amp;key=0763686c</trackback:ping></item><item><title>Redhat 9下安装php4.4.4</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/172.html</link><pubDate>Mon, 17 Sep 2007 18:56:50 +0800</pubDate><guid>http://blog.bigcomic.com/post/172.html</guid><description><![CDATA[<p><code>今天上班接到一个任务，安装webmai IlohaMail. 公司目前的邮件系统采用qmail, apache 1.3.3,操作系统是redhat 9.</code> </p><p><code>看了一下文档,IlohaMail的安装是比较容易,只要装个PHP解释器就可以跑了. 选择的PHP版本是4.4.4</code> </p><p><code>./configure --prefix=/usr/local/php --with-mysql=/usr/local/mysql --with-apxs=/www/apache/bin/apxs --enable-track-vars --enable-force-cgi-redirect --with-config-file-path=/usr/local/php/etc</code> </p><p>执行之后出错. </p><p><code><span style="FONT-FAMILY: Times New Roman">In file included from /usr/include/openssl/ssl.h:179, <br />from mod_ssl.h:125, <br />from mod_ssl.c:60: <br />/usr/include/openssl/kssl.h:72:18: krb5.h: No such file or directory <br />In file included from /usr/include/openssl/ssl.h:179, <br />from mod_ssl.h:125, <br />from mod_ssl.c:60: <br />/usr/include/openssl/kssl.h:132: parse error before &quot;krb5_enctype&quot; <br />/usr/include/openssl/kssl.h:134: parse error before &quot;FAR&quot; <br />/usr/include/openssl/kssl.h:135: parse error before '}' token <br />/usr/include/openssl/kssl.h:147: parse error before &quot;kssl_ctx_setstring&quot; <br />/usr/include/openssl/kssl.h:147: parse error before '*' token <br />/usr/include/openssl/kssl.h:148: parse error before '*' token <br />/usr/include/openssl/kssl.h:149: parse error before '*' token <br />/usr/include/openssl/kssl.h:149: parse error before '*' token <br />/usr/include/openssl/kssl.h:150: parse error before '*' token <br />/usr/include/openssl/kssl.h:151: parse error before &quot;kssl_ctx_setprinc&quot; <br />/usr/include/openssl/kssl.h:151: parse error before '*' token <br />/usr/include/openssl/kssl.h:153: parse error before &quot;kssl_cget_tkt&quot; <br />/usr/include/openssl/kssl.h:153: parse error before '*' token <br />/usr/include/openssl/kssl.h:155: parse error before &quot;kssl_sget_tkt&quot; <br />/usr/include/openssl/kssl.h:155: parse error before '*' token <br />/usr/include/openssl/kssl.h:157: parse error before &quot;kssl_ctx_setkey&quot; <br />/usr/include/openssl/kssl.h:157: parse error before '*' token <br />/usr/include/openssl/kssl.h:159: parse error before &quot;context&quot; <br />/usr/include/openssl/kssl.h:160: parse error before &quot;kssl_build_principal_2&quot; <br />/usr/include/openssl/kssl.h:160: parse error before &quot;context&quot; <br />/usr/include/openssl/kssl.h:163: parse error before &quot;kssl_validate_times&quot; <br />/usr/include/openssl/kssl.h:163: parse error before &quot;atime&quot; <br />/usr/include/openssl/kssl.h:165: parse error before &quot;kssl_check_authent&quot; <br />/usr/include/openssl/kssl.h:165: parse error before '*' token <br />/usr/include/openssl/kssl.h:167: parse error before &quot;enctype&quot; <br />In file included from mod_ssl.h:125, <br />from mod_ssl.c:60: <br />/usr/include/openssl/ssl.h:909: parse error before &quot;KSSL_CTX&quot; <br />/usr/include/openssl/ssl.h:909: warning: no semicolon at end of struct or union <br />/usr/include/openssl/ssl.h:931: parse error before '}' token <br />make[4]: *** [mod_ssl.slo] Error 1 <br />make[4]: Leaving directory `/root/tools/apache/httpd-2.0.48/modules/ssl' <br />make[3]: *** [shared-build-recursive] Error 1 <br />make[3]: Leaving directory `/root/tools/apache/httpd-2.0.48/modules/ssl' <br />make[2]: *** [shared-build-recursive] Error 1 <br />make[2]: Leaving directory `/root/tools/apache/httpd-2.0.48/modules' <br />make[1]: *** [shared-build-recursive] Error 1 <br />make[1]: Leaving directory `/root/tools/apache/httpd-2.0.48' <br />make: *** [all-recursive] Error 1</span></code> <br /><br />查找原因:&nbsp; 服务器上跑了openssl, 而redhat 9 把krb5-devel 套件把kerberos 的include文件放到了 /usr/kerberos/include里,而不是/usr/include ,因此在编译的时候就出现上面的错误.</p><p>解决方法1 建立下面三个LINK</p><blockquote dir="ltr" style="MARGIN-RIGHT: 0px"><p>ln -s /usr/kerberos/include/com_err.h /usr/include/ <br />ln -s /usr/kerberos/include/profile.h /usr/include/ <br />ln -s /usr/kerberos/include/krb5.h /usr/include/</p></blockquote><p>解决方法2 按照下面的编译方法 不过我实验没成功. </p><blockquote dir="ltr" style="MARGIN-RIGHT: 0px"><p>./configure&nbsp;--enable-so&nbsp;--with-ssl=/usr/local/openssl&nbsp;--enable-ssl </p></blockquote><p>OK&nbsp;&nbsp; 继续&nbsp; make 一下.&nbsp;&nbsp; 又出现错误 </p><blockquote dir="ltr" style="MARGIN-RIGHT: 0px"><p>-o libphp4.la<br />ext/ctype/ctype.lo: file not recognized: File truncated<br />collect2: ld returned 1 exit status</p></blockquote><p dir="ltr">这个问题浪费我了半个小时,&nbsp; 最后找到的方法非常简单make clean&nbsp; - -!&nbsp; 搞定 然后 make install . php安装完毕。</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/172.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=172</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=172&amp;key=d77c37c2</trackback:ping></item><item><title>ubuntu7.04与HP1940同步</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/170.html</link><pubDate>Thu, 13 Sep 2007 23:37:21 +0800</pubDate><guid>http://blog.bigcomic.com/post/170.html</guid><description><![CDATA[http://ubuntuforums.org/showthread.php?t=136257<br /><div class="post_content"><br />t has been requested quite a few times around the forum, i know i wish i could have found one a while ago, so here we go, the wonderful world of Synce...<br /><br />*NOTE/DISCLAIMER:*<br />Synce is NOT my project, i do NOT promise it will work, and should your machine explode, i take no responsibility (ok, fine, i take the responsibility to laugh)<br />be careful with synce, it can erase your entire PocketPC.... i would suggest using the builtin backup tool and saving the backup somewhere safe!<br />credit to:<br />Synce site<br />Storm of UbuntuForums (i used his howto for some of the linking stuff...)<br /><br /><br />alright onward and upward....<br /><br />first we need to find out where your pocketpc is in dev...thanks again to storm for this part...<br /><br />with your device unpluged type<br /><div style="MARGIN: 5px 20px 20px"><div class="smallfont" style="MARGIN-BOTTOM: 2px">Code:</div><pre class="ubuntu_codebackground" style="BORDER-RIGHT: 1px inset; PADDING-RIGHT: 6px; BORDER-TOP: 1px inset; PADDING-LEFT: 6px; PADDING-BOTTOM: 6px; MARGIN: 0px; OVERFLOW: auto; BORDER-LEFT: 1px inset; WIDTH: 554px; PADDING-TOP: 6px; BORDER-BOTTOM: 1px inset; HEIGHT: 34px"><div style="TEXT-ALIGN: left">ls /dev &gt; /tmp/before</div></pre></div>then plugin your device and type<br /><div style="MARGIN: 5px 20px 20px"><div class="smallfont" style="MARGIN-BOTTOM: 2px">Code:</div><pre class="ubuntu_codebackground" style="BORDER-RIGHT: 1px inset; PADDING-RIGHT: 6px; BORDER-TOP: 1px inset; PADDING-LEFT: 6px; PADDING-BOTTOM: 6px; MARGIN: 0px; OVERFLOW: auto; BORDER-LEFT: 1px inset; WIDTH: 555px; PADDING-TOP: 6px; BORDER-BOTTOM: 1px inset; HEIGHT: 50px"><div style="TEXT-ALIGN: left">ls /dev &gt; /tmp/after<br />diff /tmp/before /tmp/after</div></pre></div>hopefully it shows <br />ttyUSB0 (just remember wat this is!)<br /><br /><br /><br />then, you need a bunch of packages that are in the repository...<br />you can use synaptic, but im gonna write for apt-get<br /><br /><div style="MARGIN: 5px 20px 20px"><div class="smallfont" style="MARGIN-BOTTOM: 2px">Code:</div><pre class="ubuntu_codebackground" style="BORDER-RIGHT: 1px inset; PADDING-RIGHT: 6px; BORDER-TOP: 1px inset; PADDING-LEFT: 6px; PADDING-BOTTOM: 6px; MARGIN: 0px; OVERFLOW: auto; BORDER-LEFT: 1px inset; WIDTH: 549px; PADDING-TOP: 6px; BORDER-BOTTOM: 1px inset; HEIGHT: 66px"><div style="TEXT-ALIGN: left">sudo apt-get install synce-dccm<br />sudo apt-get install synce-kde<br />sudo apt-get install synce-serial</div></pre></div>(note: this guide is written for Gnome, but uses the synce-kde package... it works fine for me)<br />you need all the librarys that come with them...<br />also, this is an optional step if you wanna try and synce your PIM data with evolution (i have yet to be able to do this...partially from lack of trying tho...)<br /><div style="MARGIN: 5px 20px 20px"><div class="smallfont" style="MARGIN-BOTTOM: 2px">Code:</div><pre class="ubuntu_codebackground" style="BORDER-RIGHT: 1px inset; PADDING-RIGHT: 6px; BORDER-TOP: 1px inset; PADDING-LEFT: 6px; PADDING-BOTTOM: 6px; MARGIN: 0px; OVERFLOW: auto; BORDER-LEFT: 1px inset; WIDTH: 549px; PADDING-TOP: 6px; BORDER-BOTTOM: 1px inset; HEIGHT: 50px"><div style="TEXT-ALIGN: left">sudo apt-get install multisync<br />sudo apt-get install synce-multisync-plugin</div></pre></div>there is a howto on wat to do with multisync <a target="_blank" href="http://synce.sourceforge.net/synce/multisync_guide.php">here</a><br /><br />while installing synce-serial a config window will pop-up, check the options, default usually works fine...put in wat we found out earlier here (ttyUSB0 for me)<br /><br /><br />next you need to download and install these debs...<br /><div style="MARGIN: 5px 20px 20px"><div class="smallfont" style="MARGIN-BOTTOM: 2px">Code:</div><pre class="ubuntu_codebackground" style="BORDER-RIGHT: 1px inset; PADDING-RIGHT: 6px; BORDER-TOP: 1px inset; PADDING-LEFT: 6px; PADDING-BOTTOM: 6px; MARGIN: 0px; OVERFLOW: auto; BORDER-LEFT: 1px inset; WIDTH: 562px; PADDING-TOP: 6px; BORDER-BOTTOM: 1px inset; HEIGHT: 66px"><div style="TEXT-ALIGN: left">wget http://kuci.org/~teddy/ubuntu/synce-gnomevfs_0.9.0-2_i386.deb<br />wget http://kuci.org/~teddy/ubuntu/synce-software-manager_0.9.0-2_i386.deb<br />wget http://kuci.org/~teddy/ubuntu/synce-trayicon_0.9.0-2_i386.deb</div></pre></div>then<br /><div style="MARGIN: 5px 20px 20px"><div class="smallfont" style="MARGIN-BOTTOM: 2px">Code:</div><pre class="ubuntu_codebackground" style="BORDER-RIGHT: 1px inset; PADDING-RIGHT: 6px; BORDER-TOP: 1px inset; PADDING-LEFT: 6px; PADDING-BOTTOM: 6px; MARGIN: 0px; OVERFLOW: auto; BORDER-LEFT: 1px inset; WIDTH: 564px; PADDING-TOP: 6px; BORDER-BOTTOM: 1px inset; HEIGHT: 66px"><div style="TEXT-ALIGN: left">sudo dpkg -i synce-gnomevfs_0.9.0-2_i386.deb<br />sudo dpkg -i synce-software-manager_0.9.0-2_i386.deb<br />sudo dpkg -i synce-trayicon_0.9.0-2_i386.deb</div></pre></div>we need a link here just to get it all to work...<br /><div style="MARGIN: 5px 20px 20px"><div class="smallfont" style="MARGIN-BOTTOM: 2px">Code:</div><pre class="ubuntu_codebackground" style="BORDER-RIGHT: 1px inset; PADDING-RIGHT: 6px; BORDER-TOP: 1px inset; PADDING-LEFT: 6px; PADDING-BOTTOM: 6px; MARGIN: 0px; OVERFLOW: auto; BORDER-LEFT: 1px inset; WIDTH: 571px; PADDING-TOP: 6px; BORDER-BOTTOM: 1px inset; HEIGHT: 34px"><div style="TEXT-ALIGN: left">sudo ln -s /usr/lib/libgtop-2.0.so.5 /usr/lib/libgtop-2.0.so.2</div></pre></div>run these commands<br /><div style="MARGIN: 5px 20px 20px"><div class="smallfont" style="MARGIN-BOTTOM: 2px">Code:</div><pre class="ubuntu_codebackground" style="BORDER-RIGHT: 1px inset; PADDING-RIGHT: 6px; BORDER-TOP: 1px inset; PADDING-LEFT: 6px; PADDING-BOTTOM: 6px; MARGIN: 0px; OVERFLOW: auto; BORDER-LEFT: 1px inset; WIDTH: 571px; PADDING-TOP: 6px; BORDER-BOTTOM: 1px inset; HEIGHT: 82px"><div style="TEXT-ALIGN: left">synce-trayicon<br />dccm<br />sudo synce-serial-config ttyUSB0 (REMEMBER TO PUT IN WAT YOU NEED HERE)<br />sudo synce-serial-start</div></pre></div>now in your tray icon, u should see a synce icon... right click/explorer<br /><br />tada! all done!<br /><br />(you can now remove the debs u got from wget...)<br /><br /><br />questions, comments, patches, etc etc etc.... lemme know!</div>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/170.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=170</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=170&amp;key=06f8c6cc</trackback:ping></item><item><title>windows命令以及控制台启动命令</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/167.html</link><pubDate>Tue, 04 Sep 2007 23:15:13 +0800</pubDate><guid>http://blog.bigcomic.com/post/167.html</guid><description><![CDATA[<p>winver---------检查Windows版本<br />wmimgmt.msc----打开windows管理体系结构(WMI)<br />wupdmgr--------windows更新程序<br />wscript--------windows脚本宿主设置<br />write----------写字板<br />winmsd---------系统信息<br />wiaacmgr-------扫描仪和照相机向导<br />winchat--------XP自带局域网聊天</p><p>mem.exe--------显示内存使用情况<br />Msconfig.exe---系统配置实用程序<br />mplayer2-------简易widnows media player<br />mspaint--------画图板<br />mstsc----------远程桌面连接<br />mplayer2-------媒体播放机<br />magnify--------放大镜实用程序<br />mmc------------打开控制台<br />mobsync--------同步命令</p><p>dxdiag---------检查DirectX信息<br />drwtsn32------ 系统医生<br />devmgmt.msc--- 设备管理器<br />dfrg.msc-------磁盘碎片整理程序<br />diskmgmt.msc---磁盘管理实用程序<br />dcomcnfg-------打开系统组件服务<br />ddeshare-------打开DDE共享设置<br />dvdplay--------DVD播放器</p><p>net stop messenger-----停止信使服务<br />net start messenger----开始信使服务<br />notepad--------打开记事本<br />nslookup-------网络管理的工具向导<br />ntbackup-------系统备份和还原<br />narrator-------屏幕&quot;讲述人&quot;<br />ntmsmgr.msc----移动存储管理器<br />ntmsoprq.msc---移动存储管理员操作请求<br />netstat -an----(TC)命令检查接口</p><p>syncapp--------创建一个公文包<br />sysedit--------系统配置编辑器<br />sigverif-------文件签名验证程序<br />sndrec32-------录音机<br />shrpubw--------创建共享文件夹<br />secpol.msc-----本地安全策略<br />syskey---------系统加密，一旦加密就不能解开，保护windows xp系统的双重密码<br />services.msc---本地服务设置</p><p>Sndvol32-------音量控制程序<br />sfc.exe--------系统文件检查器<br />sfc /scannow---windows文件保护</p><p>tsshutdn-------60秒倒计时关机命令<br />tourstart------xp简介（安装完成后出现的漫游xp程序）<br />taskmgr--------任务管理器</p><p>eventvwr-------事件查看器<br />eudcedit-------造字程序<br />explorer-------打开资源管理器</p><p>packager-------对象包装程序<br />perfmon.msc----计算机性能监测程序<br />progman--------程序管理器</p><p>regedit.exe----注册表<br />rsop.msc-------组策略结果集<br />regedt32-------注册表编辑器<br />rononce -p ----15秒关机<br />regsvr32 /u *.dll----停止dll文件运行<br />regsvr32 /u zipfldr.dll------取消ZIP支持</p><p>cmd.exe--------CMD命令提示符<br />chkdsk.exe-----Chkdsk磁盘检查<br />certmgr.msc----证书管理实用程序<br />calc-----------启动计算器<br />charmap--------启动字符映射表<br />cliconfg-------SQL SERVER 客户端网络实用程序<br />Clipbrd--------剪贴板查看器<br />conf-----------启动netmeeting<br />compmgmt.msc---计算机管理<br />cleanmgr-------垃圾整理<br />ciadv.msc------索引服务程序</p><p>osk------------打开屏幕键盘<br />odbcad32-------ODBC数据源管理器<br />oobe/msoobe /a----检查XP是否激活</p><p>lusrmgr.msc----本机用户和组<br />logoff---------注销命令</p><p>iexpress-------木马捆绑工具，系统自带</p><p>Nslookup-------IP地址侦测器</p><p>fsmgmt.msc-----共享文件夹管理器</p><p>utilman--------辅助工具管理器</p><p>gpedit.msc-----组策略</p><br />]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/167.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=167</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=167&amp;key=f5f8b599</trackback:ping></item><item><title>我的公路车架</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/160.html</link><pubDate>Sun, 02 Sep 2007 03:55:24 +0800</pubDate><guid>http://blog.bigcomic.com/post/160.html</guid><description><![CDATA[经过精心测量和计算后 得到下面的数据和尺寸图, 花了我两晚时间. 明天去试车 8-) <br/><br/><table cellpadding="3" width="100%" cellspacing="0" border="0"><tbody><tr><th/><th width="150"><span class="caption">The Competitive Fit</span></th><th width="150"><span class="caption">The Eddy Fit</span></th><th width="150"><span class="caption">The French Fit</span></th></tr><tr><td class="rowlabel">Seat tube range c-c</td><td class="pricebody">51.8 - 52.3</td><td class="pricebody">53.0 - 53.5</td><td class="pricebody">54.7 - 55.2</td></tr><tr><td class="rowlabel">Seat tube range c-t</td><td class="pricebody">53.4 - 53.9</td><td class="pricebody">54.6 - 55.1</td><td class="pricebody">56.3 - 56.8</td></tr><tr><td class="rowlabel">Top tube length</td><td class="pricebody">54.2 - 54.6</td><td class="pricebody">54.2 - 54.6</td><td class="pricebody">55.4 - 55.8</td></tr><tr><td class="rowlabel">Stem Length</td><td class="pricebody">11.2 - 11.8</td><td class="pricebody">10.1 - 10.7</td><td class="pricebody">10.3 - 10.9</td></tr><tr><td class="rowlabel">BB-Saddle Position</td><td class="pricebody">68.4 - 70.4</td><td class="pricebody">67.6 - 69.6</td><td class="pricebody">65.9 - 67.9</td></tr><tr><td class="rowlabel">Saddle-Handlebar</td><td class="pricebody">52.9 - 53.5</td><td class="pricebody">53.7 - 54.3</td><td class="pricebody">55.4 - 56.0</td></tr><tr><td class="rowlabel">Saddle Setback</td><td class="pricebody">4.7 - 5.1</td><td class="pricebody">5.9 - 6.3</td><td class="pricebody">5.4 - 5.8</td></tr><tr><td class="rowlabel">Seatpost Type</td><td class="pricebody">SETBACK</td><td class="pricebody">SETBACK</td><td class="pricebody">SETBACK</td></tr></tbody></table><p><img width="564" height="351" src="http://blog.bigcomic.com/upload/mysizebkie.jpg"/><br/></p><p>http://www.competitivecyclist.com/za/CCY?PAGE=FIT_CALCULATOR_INTRO&amp;INTRO_LINK=NOREDIR</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/160.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=160</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=160&amp;key=ca358bff</trackback:ping></item><item><title>公路车的细节调整</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/164.html</link><pubDate>Sat, 01 Sep 2007 17:42:01 +0800</pubDate><guid>http://blog.bigcomic.com/post/164.html</guid><description><![CDATA[<p>近来在下见有很多新人进来,都有一些公路车子的调整问题就简略的画了些图和作了简单的解说,希望能让各位车手受用,谢谢. 如有需要增加的请提出,在下会尽量找资料来再作解答;或者有错误的,请各位大虾提出,请各位大虾提出,谢谢~~~~</p><hr/><p>刹把的位置调整 把手的刹车杆下端与把横的下部在同一直线上</p><p><img src="http://www.bigcomic.com/blog/upload/118863903376_adjust1_tn.jpg" title="adjust1.jpg" height="150" width="200" alt="adjust1.jpg" id="urn:zoundry:jid:118863903376_adjust1.jpg"/></p><hr/><p><br/>把横的位置调整 刹把安装好后,把横的上把手位置与把横杆的位置(红线:把手的弯曲处与把横中心)所成的直线与地面平衡</p><p><img src="http://www.bigcomic.com/blog/upload/adjust2_tn.jpg" title="adjust2.jpg" height="150" width="200" alt="adjust2.jpg" id="urn:zoundry:jid:adjust2.jpg"/></p><hr/><p>前拨的调整 前拨挂在大盘上,前拨道板与牙盘齿之间的距离s保持1~2mm</p><br/><p><img src="http://www.bigcomic.com/blog/upload/adjust3_tn.jpg" title="adjust3.jpg" height="150" width="200" alt="adjust3.jpg" id="urn:zoundry:jid:adjust3.jpg"/></p><hr/><br/><p>后拨的调整 后拨在调整好与飞轮之间的距离后,牙盘挂在大盘上,飞轮挂在最小飞,A臂与B臂之间成90°的夹角</p><br/><p><img src="http://www.bigcomic.com/blog/upload/adjust4_tn.jpg" title="adjust4.jpg" height="150" width="200" alt="adjust4.jpg" id="urn:zoundry:jid:adjust4.jpg"/></p><hr/><p>刹座的调整 装上轮组和刹座后,把两边的刹车胶与车圈的距离s都调整到1`2mm</p><p><img src="http://www.bigcomic.com/blog/upload/adjust5_tn.jpg" title="adjust5.jpg" height="150" width="200" alt="adjust5.jpg" id="urn:zoundry:jid:adjust5.jpg"/></p><hr/><p>座包的调整 座包的平面与地面平衡</p><p><img src="http://www.bigcomic.com/blog/upload/adjust6_tn.jpg" title="adjust6.jpg" height="150" width="200" alt="adjust6.jpg" id="urn:zoundry:jid:adjust6.jpg"/></p><hr/><p>座高的调整</p><p>骑手坐在车座上,盘骨保持平衡,一边的腿伸直,脚跟放在踏板上,刚好把腿伸直就是适合座高</p><p><img src="http://www.bigcomic.com/blog/upload/adjust7_tn.jpg" title="adjust7.jpg" height="150" width="200" alt="adjust7.jpg" id="urn:zoundry:jid:adjust7.jpg"/></p><hr/><p>座位前后调整</p><p>调整好座高后,把脚掌放到平常习惯的踏板位置上,B线与地面垂直</p><p><br/><img src="http://www.bigcomic.com/blog/upload/adjust8_tn.jpg" title="adjust8.jpg" height="150" width="200" alt="adjust8.jpg" id="urn:zoundry:jid:adjust8.jpg"/></p><br/><br/><br/><br/><br/><br/><br/>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/164.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=164</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=164&amp;key=50e1f844</trackback:ping></item><item><title>2007 Ridley Noah Geometry</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/163.html</link><pubDate>Sat, 01 Sep 2007 12:06:04 +0800</pubDate><guid>http://blog.bigcomic.com/post/163.html</guid><description><![CDATA[<table cellpadding="3" width="100%" cellspacing="0" border="0" class="prodGeoTitletable"><tbody><tr><td class="tablecaption"><h2 align="center" class="caption">2007 Ridley Noah Geometry</h2></td></tr></tbody></table><table cellpadding="3" width="100%" cellspacing="0" border="0" class="prodGeometrytable"><tbody><tr style="FONT-FAMILY: Tahoma,sans-serif"><th>Size</th><th>Seat Tube c-c</th><th>Seat Tube c-t</th><th>Actual Top Tube</th><th>Effective Top Tube</th><th style="FONT-FAMILY: Tahoma,sans-serif">Head Tube</th><th>Seat Angle</th><th>Head Tube Angle</th></tr><tr><td class="pricebody">XS</td><td class="pricebody">44.0</td><td class="pricebody">48.0</td><td class="pricebody">51.0</td><td class="pricebody">52.5</td><td class="pricebody">13.0</td><td class="pricebody">74.0</td><td class="pricebody">72.0</td></tr><tr><td class="pricebody">S</td><td class="pricebody">47.0</td><td class="pricebody">51.0</td><td class="pricebody">53.0</td><td class="pricebody">54.5</td><td class="pricebody">14.5</td><td class="pricebody">73.5</td><td class="pricebody">73.0</td></tr><tr><td class="pricebody">M</td><td class="pricebody">50.0</td><td class="pricebody">54.0</td><td class="pricebody">55.0</td><td class="pricebody">56.5</td><td class="pricebody">17.5</td><td class="pricebody">73.0</td><td class="pricebody">73.5</td></tr><tr><td class="pricebody">L</td><td class="pricebody">53.0</td><td class="pricebody">57.0</td><td class="pricebody">57.0</td><td class="pricebody">58.5</td><td class="pricebody">20.5</td><td class="pricebody">72.5</td><td class="pricebody">73.5</td></tr><tr><td class="pricebody">XL</td><td class="pricebody">56.0</td><td class="pricebody">60.0</td><td class="pricebody">58.5</td><td class="pricebody">60.0</td><td class="pricebody">23.0</td><td class="pricebody">72.5</td><td class="pricebody">74.0</td></tr></tbody></table><br/><p style="TEXT-ALIGN: center"><img src="http://www.bigcomic.com/blog/upload/geometry_sloping_tn.jpg" style="DISPLAY: inline; WIDTH: 522px; HEIGHT: 208px" title="geometry_sloping.gif" height="208" width="522" alt="geometry_sloping.gif" id="urn:zoundry:jid:geometry_sloping.gif"/></p><p><br/></p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/163.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=163</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=163&amp;key=f4502843</trackback:ping></item><item><title>How to Fit a Bicycle by Peter Jon White</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/161.html</link><pubDate>Sat, 01 Sep 2007 02:48:26 +0800</pubDate><guid>http://blog.bigcomic.com/post/161.html</guid><description><![CDATA[<p style="TEXT-ALIGN: center"><span class="logtext"><span style="FONT-SIZE: 1.2em"><span style="COLOR: #990000">Overview</span></span></span></p><p>Bicycle fitting is a subject most people find quite mysterious. Fitting systems with charts and graphs, computer software, measuring devices and "rules of thumb" make for a lot of confusion. But I believe it's really quite simple. Bicycle fit involves compromises. Compromises between comfort and performance, quick acceleration and handling stability, top speed and "taking in the scenery".</p><p>Your body's position on the bike affects how you ride. It affects how much power you can efficiently deliver to the pedals. It affects how comfortable you are on the bike. A position that is more comfortable may not allow you to put as much energy into moving the bike forward as a less comfortable position might. How do you decide where to position your body on the bike?</p><p>Ask yourself, "What do I want to do with my bike?", "Why am I riding?". A track sprinter is not the least bit concerned with how comfortable he is sitting on the bike. During the race, (which may last for less than a minute), he may only be seated for 5 or 10 seconds. A long distance tourist traveling coast to coast across the USA might spend 5 to 12 hours a day in the saddle, day after day. He is probably far more concerned with being comfortable and enjoying the scenery than with going as fast as he can.</p><p>This article relates only to traditional road and mountain bicycles. I know next to nothing about recumbent bicycles and have absolutely no advice to offer regarding recumbent fitting.</p><p style="TEXT-ALIGN: center"><span style="FONT-SIZE: 1.2em"><span style="COLOR: #990000">Let's get started</span></span></p><p>Your body contacts the bicycle in three areas; your hands, your seat, and your feet. The relative positions of feet, seat and hands determine your comfort and efficiency on the bike. There are several variables that determine these positions; crank length, distance from crank center or bottom bracket to saddle, saddle angle, seat tube angle and saddle offset, distance from saddle to handlebar, relative height of saddle and handlebar, handlebar width, and handlebar drop on road style handlebars. I'll discuss each of these variables.</p><p style="TEXT-ALIGN: center"><span style="FONT-SIZE: 1.2em"><span style="COLOR: #990000">Crank Length</span></span></p><p>Crank length determines the diameter of the circle that the pedals move in. The larger that circle is, the more flexion of your knee and thigh muscles will be needed to turn the cranks. Your thigh muscles cannot exert the same force throughout their range of motion. This is very easy to demonstrate. If you squat down so that your knees are fully bent and lift yourself up, say, five inches, it takes a good deal more effort than it would to squat down just five inches from standing straight and then lift yourself back up. At the full squat position, your muscles can't put out the same power as when your knees are just bent enough to drop you down five inches. So if you had to choose between a crank length that had your knees bending through their entire range of motion and a length that only required, say, 20 degrees of flexion at the knee, you would choose the shorter crank. That crank would have your muscles working through a more efficient range of motion. You would avoid having to flex your knees enough to bring you into an inefficient range of motion.</p><p>So how long should the cranks be? Well, that's a good question. I wish I had a good answer but I don't. It should be obvious that a 5' 2" rider would not want to use the same length crank arms as a 6' 7" rider unless they somehow managed to have the same leg length (highly unlikely). Some research has been done to determine the optimum percentage of leg length to crank length. I doubt that there is an optimum percentage that would apply to all people. One writer in a major magazine article quite a few years ago claimed that after considerable testing with many different riders, 18.5% of the distance from the top of the femur to the floor in bare feet should be the crank length. You can find the top of the femur pretty easily. It's 5" to 6" below your hip bone, and moves rearward when you raise your knee. After reading this I promptly changed from the industry standard 170mm cranks for road bikes to 175mm cranks. There was an immediate improvement in power and endurance. I began using this formula when recommending cranks to my customers. So far, I haven't gotten any complaints. But of course that doesn't mean my customers wouldn't be as happy or happier with some other length. And I must admit that I have never tried still longer cranks than 175mm for enough time to tell if I would be even happier with them.</p><p>The top of the femur measurement ignores differences in legs themselves. Differences in the proportion of calf length to thigh length should affect the optimum crank length. A rider with longer thighs and shorter calves would use a longer crank to get the same flexion at the knee as a rider with short thigh and long calf. Of two riders with the same body proportions, one might prefer to pedal at a faster cadence. That might favor a shorter crank length. And perhaps even two riders with identical skeletal proportions would find after testing that they required different crank lengths to achieve maximum performance due simply to differences in their muscles.</p><p>Trying different cranks to find the optimum length would be time consuming and expensive, but I believe it is the only way to determine the correct length for any individual, assuming there is a correct length. It would be nice to have a crank with many pedal threads at various lengths to test. But I know of no such thing being made and I lack the ability to make one! Of course, some riders with multiple bikes report being just as happy on one crank length as another. Go figure! So, for lack of a better system, I'm staying with the 18.5% guide for my customers until something better comes along. It hasn't failed yet.</p><p>In the United States, it has been difficult and expensive to obtain cranks shorter than 165mm or longer than 175mm. But a French company, Specialites TA has been making high quality cranks in lengths of 150mm through 185mm for many years. In order to offer my customers better fitting bicycles, I've decided to sell these cranks. See my web page; <a href="http://www.peterwhitecycles.com/zephyr.asp">http://www.PeterWhiteCycles.com/Zephyr.asp</a> for details.</p><p style="TEXT-ALIGN: center"><span style="FONT-SIZE: 1.2em"><span style="COLOR: #990000">Saddle Height</span></span></p><p>Once the crank length is determined, (by whatever means), the saddle should be set at a nominal height. There is no objectively determined ideal saddle height for any rider based on leg length alone. Some riders naturally pedal toes down, while others have the foot in a more level position. For starters, sit on the saddle with one leg hanging free and your hips square, (not tilting to either side). Set the saddle high enough so that your other heel can just touch the pedal with your leg straight, and with the pedal at the bottom of the stroke, in line with the seat tube. For most people this results in a saddle height that leaves some bend in the knee at the bottom of the pedal stroke, when you're pedaling with the balls of your feet over the axle of the pedals. It also should prevent you from having to rock your hips through each crank rotation. This gets you close enough to your optimum saddle height that you can go through the rest of the fitting process and fine tune saddle height later. Any later saddle height adjustments shouldn't be enough to throw off the other adjustments.</p><p style="TEXT-ALIGN: center"><span style="FONT-SIZE: 1.2em"><span style="COLOR: #990000">Saddle Angle</span></span></p><p>In order to fit a bicycle, you need a saddle you can sit ON. That may seem too obvious to even mention. But sadly, most bikes seem to be sold with saddles designed by people who have never ridden a bicycle. In order to ease the pain of using these implements of torture, people often angle the saddle with the nose down. This makes it impossible to sit ON the saddle. You tend to slide forward. You end up pushing against the handlebar just to keep yourself on the saddle. Get yourself a saddle you can sit on so that your pelvis is resting on a level surface. For most saddles that would put the nose of the saddle a bit higher than the rear. Women's saddles should be wider than men's since a woman's pelvis is wider. Many women's saddles now have a cutout or low density foam section in the center to take pressure off the pubic bone while allowing a level saddle position. The closer you can get to a level platform, the easier it will be to find the best fore-aft position of saddle and handlebar.</p><p style="TEXT-ALIGN: center"><span style="FONT-SIZE: 1.2em"><span style="COLOR: #990000">The Fore-Aft Saddle Position</span></span></p><p>Now we get to what I think is the most important part of fitting a bicycle, the fore-aft position of the saddle. Once you get this right, everything else is easy. This position is determined more by how you intend to use your bike than by anything else. If you look at a typical bike, the saddle is behind the crank center, or bottom bracket. There's a frame tube (the seat tube) running from the cranks to the saddle, and it's at an angle. That angle partly determines the fore-aft position of the saddle relative to the cranks and pedals. That fore-aft position determines how your body is balanced on the bicycle. Your balance determines how comfortable you are, and how efficiently you can pedal the bike.</p><p>Stand up straight in front of a mirror and turn to the side. Look at yourself in the mirror. When standing straight your head, hands, seat and feet are all fairly close to being in line with each other. Now bend over at the waist. Notice that not only has your head moved to a position ahead of your feet, but your rear end has moved behind your feet. If this were not the case, you would fall forward. Your seat moves back when you bend at the waist to keep you in balance.</p><p>Your torso needs to be leaning forward for two reasons; power output and aerodynamics. With an upright torso, you can't use the gluteus muscles to good effect. Also, you can't effectively pull up on the handlebar from an upright position. An upright torso is also very poor aerodynamically. When cycling on level ground, the majority of your effort goes against wind resistance. The easier it is for your body to move through the air, the less work you'll have to do. With your torso closer to horizontal, you present less frontal surface to the air and don't have to work as hard to maintain a given speed.</p><p>Obviously, the most aerodynamically efficient position may not be the most pleasant position to be in for several hours on a cross country tour. So there's a tradeoff. As you move to a more horizontal position, the saddle needs to be positioned further to the rear to maintain your body's balance, just as your rear end moves to the rear as you bend over while standing. It so happens that racers are more inclined to use a horizontal torso position than tourers, and racers are more concerned with having the handlebars further forward to make climbing and sprinting out of the saddle more effective.</p><p>If a bicycle had the saddle directly over the cranks, you wouldn't be able to lean your body forward without supporting the weight of your torso with your arms. Because the saddle on a typical bicycle is behind the cranks, your seat is positioned behind your feet and your body can be in balance. Try this test. You'll need a friend to hold the bike up, or set it on a wind trainer. Sit on your bike with your hands on the handlebars and the crank arms horizontal. If you have a drop bar, hold the bar out on the brake hoods. Try taking your hands off the bar without moving your torso. If it's a strain to hold your torso in that same position, that's an indication of the work your arms are doing to hold you up.</p><p>For starters, I like to put the saddle in the forward most position that allows the rider to lift his hands off of the handlebar and maintain the torso position without strain. You should not feel like you're about to fall forward when you lift off the handlebar. If it makes no difference to your back muscles whether you have your hands on the bars or not, you know that you aren't using your arms to support your upper body. If you are, your arms and shoulders will surely get tired on a long ride. But this is a starting position. Remember that bicycle fit is a series of compromises.</p><p>So what's being compromised? Power. There's a limit to how far you can comfortably reach to the handlebar while seated. If the saddle is well back for balance, the handlebars will need to be back as well. But to get power to the pedals while out of the saddle, it helps to have the handlebars well forward of the cranks. Particularly when climbing out of the saddle, the best position tends to be had with a long forward reach to the bars. You can tell this is so by climbing a hill out of the saddle with your hands as far forward on the brake lever tops as you can hold them, then climbing the same hill with your hands as far to the rear as you can on the bars. Chances are you can climb faster with your hands further forward. So you need to find the best compromise between a comfortable seated position and reach to the handlebar, and a forward handlebar position for those times when you need to stand. Only an inch or two in handlebar placement fore-aft can make a big difference while climbing. That same inch or two in saddle position can mean the difference between a comfortable 50 mile ride and a stiff neck and sore shoulders!</p><p>As you move the saddle forward from that balanced position, you'll have more and more weight supported by your arms, but you'll be able to position the handlebars further forward for more power. The track sprinter has the frame built with a rather steep seat tube angle, which positions the saddle further forward from where the tourer would want it. But again, the track sprinter spends very little time in the saddle.</p><p>If you can't move your saddle forward enough or backward enough for the fit you want, don't despair. Different saddles position the rails further ahead than others, giving more or less saddle offset. Seatposts are available with the clamps in different positions relative to the centerline of the post.</p><p>So, how do YOU want to balance on YOUR bike? Do you want to emphasize speed and acceleration? Do you care mostly about comfort and enjoying the scenery? The answers to these questions determine how you position the saddle, not some computer program or someone's system of charts and graphs. How your best friend fits his bike should have no bearing on what you do even if he has exactly the same body proportions as you. YOU know why you ride a bike. Only YOU know what compromises you are willing to make in order to achieve your purposes on a bicycle.</p><p>You may have a bicycle for short fast rides, and another for long tours. Just as the two bikes will have different components so as to be well suited for their purposes, so might the fit be different. The rider hasn't changed. You are still you. But your purpose has changed. The light, fast bike for short rides will likely have a more forward and lower handlebar position than the tourer. And so the saddle may well be further forward too.</p><p style="TEXT-ALIGN: center"><span style="FONT-SIZE: 1em"><span style="FONT-SIZE: 1.2em; COLOR: #990000">What about knee over the pedal axle?</span></span></p><p>Most fitting "systems" specify that some part of your knee be directly over the pedal axle at some alignment of the crank, usually with the pedal forward and the crank horizontal. This is pure nonsense. Imagine two riders, almost identical, but one rider's knees are 1 inch lower than the other's. In other words, the thigh bones of one rider are 1 inch longer than the other, and his lower legs are 1 inch shorter. Everthing else about these two riders is identical, including overall height, torso length, arm length and weight. If you position the saddle such that the knee is directly over the pedal axle, the rider with the shorter thighs must have his saddle a little under 1 inch further forward of the other rider. It would be exactly 1 inch if his thigh was horizontal at that pedal position, which it isn't likely to be.</p><p>But with the saddle positioned forward, the rider with shorter thighs now has more weight that must be supported by his arms, all because of this arbitrary rule about having your knee over the pedal axle. This makes no sense. What matters is your weight distribution fore and aft, and that's determined by the fore-aft position of the saddle relative to the cranks.</p><p style="TEXT-ALIGN: center"><span style="FONT-SIZE: 1.2em"><span style="COLOR: #990000">Handlebar Position</span></span></p><p>Next, where does the handlebar go? Just like the saddle, it all depends on what it is you're doing on a bike in the first place. The further forward the bar, the more power you will have standing and accelerating, the better the aerodynamics and high speed control. The lower the bar, the more you can pull up under hard acceleration and the better the aerodynamics. With the bar closer to you and/or higher, you can sit more upright and take in the view.</p><p>I like to use an adjustable stem that my customers can use for a few days to try different positions for a long enough time to be meaningful. But what about a starting point? For riders with drop bars, if you place your hands down in the drops at the forward most position, (the point that allows you to easily reach the brake levers), then bend your elbows enough that your forearms are horizontal, your elbow would be at a ninety degree angle for a good starting point. From there, try moving the bar in one half inch increments forward and back to find the best reach for you. Most people are quite comfortable just with the ninety degree elbow position. But that doesn't mean it's right for you. And of course this isn't a position you'd want to spend much time riding in, except on the occasional banzai descent down a mountain pass!</p><p>Racers generally end up with the handlebar height two to three inches below the saddle height, tourers will often like to have the bar at the same height as the saddle. Mountain bikers usually position the bar a couple of inches below the saddle. The important thing is to take enough time to find the best position for you. If that means setting up a touring bike with the handlebar four inches below the saddle height, so be it. I recommend the longest reach and lowest position you feel comfortable in, (with emphasis on comfortable).</p><p style="TEXT-ALIGN: center"><span style="FONT-SIZE: 1.2em"><span style="COLOR: #990000">Handlebar width (road &amp; ATB) and drop for road style bars</span></span></p><p>A few brands of drop style bars come with a choice of how much lower the drop section of the bar is from the top. Unless you are a track sprinter or a criterium racer, you don't need the very deep drop bars. Most bars come in a selection of widths. Most people seem happiest with their hands positioned on the bar at about the same distance apart as the width of their shoulders, so that your arms are roughly parallel when reaching to the bar. When determining stem dimensions, try the different bar widths available, starting with one that's the same as your shoulder's width. Then see which works best for you.</p><p style="TEXT-ALIGN: center"><span style="FONT-SIZE: 1.2em"><span style="COLOR: #990000">Fine tune saddle height</span></span></p><p>As you get familiar with the way your bike feels with these changes, go back to the beginning and check your saddle height again. You should be able to pedal through the bottom of the stroke without completely straightening your knees, and without rocking your hips on the saddle. If either is the case, your saddle is too high. Straightening your knee during the pedal's rotation limits how fast you can smoothly rotate the pedals, and causes you to want to use a higher gear than that which would be most efficient. By limiting the extension of your legs you smooth out your pedaling and make higher RPMs possible. That's better for your muscles and joints. If the saddle is too low you'll feel it in your quadriceps or thigh muscles.</p><p style="TEXT-ALIGN: center"><span style="FONT-SIZE: 1.2em"><span style="COLOR: #990000">Stock frame sizing</span></span></p><p>So what does all this mean when it comes to pick a frame size down at your local bike shop? Stems and seat posts come in lots of different configurations. That means you can choose from several different frame sizes and still get the same good fit.</p><p>All other things being equal, a longer top tube will give you a bike with a longer wheelbase, less twitchy handing, better shock absorption, and require a shorter reach stem. Since the down tube, (which connects the bottom bracket with the head tube) will be longer, it can twist a bit more making the frame somewhat less stiff while accelerating, so there is a performance penalty.</p><p>A longer seat tube will allow for a higher handlebar position with the same stem and give more room for pumps and water bottles. It can also prevent you from getting as low a handlebar position as you may want. Most importantly though, the longer seat tube raises the top tube and decreases stand-over clearance, something you should give careful consideration to.</p><p style="TEXT-ALIGN: center"><span style="FONT-SIZE: 1.2em"><span style="COLOR: #990000">Methodology</span></span></p><p>Notice that in most of this there is no mention of measuring body parts. And nowhere do I have you dropping plumb lines from knees, positioning handlebars so they block views of front hubs, comparing the length of your forearm to the distance between the front of your saddle to your handlebar, etc. My methodology is quite different from what most people are doing in bike shops. The Fit Kit and other marketed fitting systems are based on the measurements of lots of different riders and their bikes. It assumes that the averages of those measurements are somehow going to result in a good fit for you.</p><p>But take the case of two riders; Rider A, and Rider B. Rider A has very little upper body muscle but very strong legs. Rider B is identical to Rider A but has been working out at Ralph's Gym and looks like a body builder. The fore aft position of the saddle will be slightly different for the two riders. The extra upper body mass of Rider B will require a slightly further back saddle position to give the same balance. But that doesn't necessarily mean that Rider B should have his saddle further back. He may prefer the more forward position. Only he knows what his preference is.</p><p>Take me for example. I started riding long distances in the mid 1970s. After much trial and error, I arrived at a bike fit that worked for me. I could ride a century without much fatigue. I still have a bike that's set up exactly like the racing style bike I rode back then. I haven't gotten any taller, or shorter. My arms haven't grown or shrunk. But my neck and back are a lot stiffer in 2001 than they were in 1975. The low handlebar position is still great while I'm climbing a hill, but on the flat after 60 miles my neck isn't as comfortable as it once was. A higher handlebar is called for now that I'm older.</p><p>Measuring my body wouldn't tell me that the handlebar needs to be higher. But I used to be comfortable in the drops, (the lower part of a road handlebar). Now, I can't see the road ahead of me if I'm in the drops.</p><p>Somewhere between the fit of the track racer's bike and the long distance tourer's bike is where most of us want to be. But each of us has to find that point for ourselves. Remember, there is only one expert when it comes to fitting your bike. Only you know how you feel on your bike. Only you know what compromises you are willing to make while riding. You're the expert!</p><p>By the way, for reasons that escape me, I frequently get email from folks who tell me that they read my fitting article, loved it, and have a question. They then tell me how long their arms, legs and torso are, proceed to inform me that some bike shop wants to sell them a particular bike, and want to know if I think the bike would fit them well. My reaction is to wonder whether I wrote the article clearly, or if they read it but didn't understand it, or if they just hadn't read it. I sometimes go back and reread my own article, assuring myself that yes indeed I did make my ideas clear, and for whatever reason the person just didn't get it. Oh well...</p><p>So I'll take this opportunity to rephrase myself. I don't know if a particular bike will be a good fit for you. Even if I knew every dimension of the bike, and every dimension of you, I couldn't tell you if it's a good fit or not. So please don't write asking me to tell you something that I can't possibly know. Reread the article.</p><p>If you need an authority figure to tell you how your bike should fit, then by all means go to some shop that offers the Fit Kit or some such thing, pay them whatever they charge, and do as they say. Some folks need to be told what to do. But I don't want to tell you what to do. I'd rather give you the knowledge you need to fit yourself. Because with that knowledge, I believe you can do a much better job of it than some expert charging you money.</p><p>And, by the way, I'm a bike mechanic, not a doctor. So if your knee or back or neck or wrist hurts, and you've set your bike up using the information in this article, well, I suppose you could sue me, but please don't expect me to diagnose your ailment. See a doctor. Then sue me. ;-)</p><p style="TEXT-ALIGN: center"><span style="FONT-SIZE: 1.2em; COLOR: #990000">By the Way</span></p><p>This article is for your information only. It's not intended as the jumping off point for a conversation about bicycle fit. I'd like to discuss it with everyone who reads it, but unfortunately if I did that I'd have no time to build wheels, which is how I make my living. I don't do bicycle fittings any longer. Nor do I have the time to respond to or even read all of the mail I get regarding this article. So, when you write to me and I don't reply, don't feel as though I've singled you out. I no longer reply to any email on this topic. No time. Sorry.</p><p><a href="http://www.peterwhitecycles.com/">http://www.PeterWhiteCycles.com</a></p><p><br/></p><hr/><p><br/></p><p>〈How to fit a bicyle〉 译文 by Fulun</p><p>對大多數人來說，自行車尺寸的選擇顯得十分的神秘。一些包含了繪圖作表，電腦軟體輔助，各種測量儀器以及"拇指準則"的選擇系統讓人困惑不解。可我認為這一切其實十分簡單。車輛尺寸的選擇需要綜合考慮，比如舒適程度和騎乘性能，加速性和操縱穩定性，高速和休閒的騎感之上。<br/>你的身體在自行車上的位置直接影響到你的騎行。它影響蹬踏力量的傳導效率，也影響到你的騎乘舒適程度。一個讓你感覺更舒服的位置會使你擁有更多能量蹬踏。那麼，你應該如何決定身體所處的位置呢？<br/>問你自己吧，"你打算用自行車來幹什麼？"，你騎行的目的是什麼呢？一名場地自行車手根本就不會考慮他是否輕鬆舒適，在比賽中（整個過程也許不到一分鐘），他也許僅僅只需要坐上5-10秒鐘。而一位橫穿美洲大陸的長途旅行者也許每天要花上5-12個小時呆在他的坐墊上。比起選手的高速度，他大概更關心的是能否騎得舒服並享受沿途的風光。<br/>這篇文章僅涉及到傳統的公路和山地自行車。我對斜躺式的自行車一無所知，當然對它的尺寸選擇也就無能為力了。<br/>你的身體有3個部位和自行車直接接觸，手，臀部，腳。這3個部位在車上的相對位置就決定了你在車上的舒適程度以及騎行的效率。有幾個數值決定了這些位置的所在：曲柄的長度、五通中心到坐墊的距離、坐墊的角度、坐墊表面的材料、坐墊和車把之間的距離、坐墊和車把到地面的高度。車把的寬度、以及公路車把的下垂的角度。我會逐條的討論這些。</p><p>曲柄的長度<br/>曲柄的長度決定了你蹬踏所產生的圓周直徑。直徑越大，你的膝蓋和大腿的肌肉就要加大伸縮幅度才能蹬動曲柄。在整個運動的過程中，你的大腿肌肉的承受力並不相等。這一點很好證明：下蹲，並使你的膝蓋完全彎曲，然後站直。這時，你就會花費比只下蹲15釐米然後再站直所消耗的更多的精力，在完全下蹲的情況下，肌肉所用的力量也並不相同。所以，當你不得不面對僅有兩種選擇的情況：<br/>1、曲柄的長度使你的膝蓋在整個圓周運動的過程中都處於彎曲的狀況；<br/>2、合適的曲柄長度：使你的膝蓋屈伸幅度在20度角左右。你最好還是選擇較短的曲柄，它會使你的肌肉在整個運動的過程中更有效率，而且不會使你的膝蓋做大幅度的屈伸而導致無用功。<br/>那麼，究竟多長的曲柄才比較合適呢？這個問題提的好，我希望我能對此有很好的答案，可惜我沒有。不過有一點非常明顯：一名身高170釐米的車手肯定不會想到去使用和身高180的車手所用的一樣長的曲柄，除非他們的腿長恰好一般長（這種情況是非常罕見的）。一些已有的研究表明了腿長和曲柄長度的最佳百分比，但我懷疑是否真的有一個最佳的百分比來適合所有人。好幾年前，一位作者在一份權威性的雜誌上宣稱，經過與許多不同的車手的大量實驗，在赤腳的情況下，從股骨的頂端到地面距離的18.5%就是所需的曲柄長度。你可以很容易的發現股骨頂端的位置，它大概處於你的盆骨下端12.5~15釐米。當你抬起膝蓋的時候，它就向後運動。讀了這篇文章之後，我迅速的把我那符合工業標準的170MM長的曲柄換成了175MM長的。我的蹬踏的力度和耐力馬上得到了改善。於是，當我向我的顧客推薦曲柄的時候，我開始使用這條規律。一直以來我都沒有受到任何的投訴。當然，這並不意味著我的顧客不喜歡使用其他長度的曲柄，而且我也必須承認我從來沒有花費足夠的時間使用長度超過175MM的曲柄並由此判斷我是否喜歡他們。<br/>對股骨頂端的測量忽視了腿部本身的差異。從小腿長度到大腿長度的局部差異將會影響到最佳的曲柄長度。和大腿短、小腿長的車手相比，一位大腿長、小腿較短的車手應該使用較長的曲柄來使膝蓋的伸縮幅度相同。<br/>如果有兩位身體條件相似的車手，其中一名喜歡採用較快的頻率騎行，那麼他很可能會比較鍾愛較短的曲柄。兩位骨骼完全相同的車手很可能經過實驗後會發現：僅僅因為肌肉條件的不同，他們需要使用不同長度的曲柄，才能使他們自身的水平發揮得淋漓盡致。通過試用不同的曲柄來找到適合自己的最佳長度，這個過程既耗時又費錢。我相信這是每個人判斷正確的曲柄長度的唯一方法，當然先得假設這個長度的曲柄確實存在。把各種長度的曲柄，裝上各種各樣腳踏進行測試，這看起來確實很不錯。但我知道這事從來沒有人幹過，我自己也做不來。當然，也確實有很多不同類型的車手說道曲柄長度的差異並沒有給他們帶來什麼不同的感覺。自己琢磨吧！在沒有更好的測量系統之前，我還是堅持使用18.5%的理論來引導我的顧客。它至少沒有出過岔子。</p><p>坐墊的高度<br/>曲柄長度確定了，（不論用什麼方法），坐墊就應當調整到合適你的高度。對於任何一個車手來說，都不該僅僅根據腿的長度就對坐墊的高度下結論。有的車手可能會自然的使用前腳掌進行蹬踏，而其他人則讓自己的腳掌處於更為平坦的位置。對於初學者來說，坐上你的坐墊，騰出一隻腳，自然下垂，擺正你的臀部（不要偏向任何一邊），把坐墊調到足夠的高度，使得你的另一隻腳的腳跟能夠在你的腿伸直的情況下剛好夠到踏板。這時候踏板的位置也應當處於座杆和五通延長線的最低點。對大多數人來說，這個坐墊高度會使你的膝蓋在踏板的軸上做圓周運動並到達最低點的時候有少許的彎曲，同時防止你的臀部隨著曲柄的轉動而左右搖晃。這樣，適合你的坐墊高度就基本確定下來了。你可以通過其他部件的尺寸選擇程式後在對其進行細微的調整。對坐墊高度的後期調整不會對其他部件的調整造成什麼影響。</p><p>坐墊的角度<br/>為了能和車子熔為一體，你需要一個能坐在上面的坐墊。這話聽起來毫無意義。可令人遺憾的是，大多數出售的自行車上面坐墊似乎都是由那些從來沒有騎過車的外行人來裝配的。為了緩解使用這些刑具所帶來的痛苦，人們經常會把坐墊的前部調低，使坐在坐墊上成為一件不可能的事情。你會向前滑，這時你就得通過向車把施力來使自己的身體固定在坐墊上。找到一個你自己能夠坐在上面的坐墊，使你的骨盆能夠呆在一個平坦的表面上。此時，大多數的坐墊前部都會比他的後部要高一些。因為女性的骨盆更寬一些，所以女式坐墊也會比男式坐墊更寬一些。現在許多女式坐墊中央都有一個孔或者是塑膠的凹槽，其主要作用是平坐在坐墊上時分散對恥骨的壓力。坐墊越平坦，你就越容易找到坐墊和車把之間的最佳位置。</p><p>坐墊的前後位置的調整<br/>現在讓我們來到我認為是自行車尺寸選擇中最重要的部分：坐墊的前後調整。一旦你弄清楚了這點，其他的就很簡單了。這個位置比其他的位置更多的決定了你打算如何使用你的車輛。我們來看一輛典型的車子，它的坐墊的位置一般都處於曲柄中間或五通的後部，在從曲柄到坐墊之間有一根車架的直管（坐管），坐管有一定的角度。這個角度部分決定了坐墊相對於曲柄和腳踏的前後位置，而這個位置又決定了你的身體在車上的平衡程度，而平衡程度又決定了你的舒適程度和蹬踏效率。<br/>站直然後側對著鏡子，仔細觀察你自己。當站直的時候，你的頭、手、足和臀部幾乎是在同一條直線上的。然後彎下腰，注意到僅僅只是你的頭部超過了你的腳，但你的身體後部的位置卻處在你的腳後。如果不這樣，那你就會向前跌到。在你彎腰的時候，你的臀部向後移動以保持身體的平衡。<br/>有兩個理由需要你的身體前傾：力量的輸出和空氣動力學。如果你挺直身體，那你的肌肉就不能很好的運動，不能使你有效的把車子停住。一個挺直的身軀也不符合空氣動力學原理。在平坦路面騎車的時候，風阻是你受到的主要阻力。如果你的身體越容易穿過空氣，那麼你所花的能量就越小。當你的身體越接近水平線的時候，身體的正面迎風面積就越小，你也就不需要消耗太多的能量來保持速度了。<br/>很明顯，在連續幾小時的越野騎行過程中，最符合空氣動力學的位置並不是讓人愉快的位置。因此我們需要綜合考慮。當你的身體越接近水平的位置，你的坐墊就應該越向後調以保持身體的平衡。這和你彎腰時身體後部向後移動的餓情況一樣。相比較之下，賽車手們會比旅行者們更傾向于使用接近水平的姿勢騎行，並且喜歡把車把往前調使他們在爬坡和衝刺時的站立騎行更為有效。<br/>如果一輛自行車的坐墊位置處於曲柄的正上方假設沒有手臂支撐你的體重，你就不能使自己的身體前傾。因為在一般的自行車上，坐墊的位置是處於曲柄延長線的正上方。試著做下面這個實驗，你需要你的朋友幫忙扶車，或者把車固定在訓練臺上。坐在車上手扶車把，並使曲柄臂處於水平位置。如果你使用的是一個公路的彎把，那麼請握住手柄彎曲部位底部，嘗試鬆開手把而不移動你的身體。如果你感到身體的肌肉繃緊了，那就意味著你的手臂承擔了你的體重。<br/>對於初學者，我建議他們把坐墊的位置調節到鬆開車把並保持原來的姿勢時身體的肌肉也不會感到緊張的位置。當你提起車把的時候，你不會喜歡自己似乎要向前跌出去的感覺。是否鬆開車把對你的背部肌肉沒有什麼影響，因為你知道你不是用你的手臂來支撐自己的上身。反之，你的雙肩和手臂就會在長途的旅行中感到疲勞。但這一切僅僅只是一個開始，記得自行車尺寸的選擇是不斷綜合考慮的結果。<br/>那麼，什麼因素應當綜合考慮呢？力量，當你坐在車上時，它就限制了你能舒適的握住車把的距離。當坐墊為了保持平衡向後調整時，車把的位置也應當相應向後調整。但是為了能在離開坐墊騎行時能將足夠的力量傳遞給腳踏，將車把到曲柄前端的距離作出相應的調整會有所幫助。尤其是當你站立式爬坡騎行的時候，最好的位置是應當和車把之間有一個較長的距離。你也可以這樣判斷，在站立式爬坡騎行的過程中，你的雙手盡可能的前伸來握住刹車手把的頂部。然後在爬同一座山的時候，你的手盡可能的握住車把的後部。你會發現，當你的手向前伸得越多的時候，你就能爬的越快。因此你就得在舒適騎乘的位置和盡可能的將車把前伸之間找到一個折中點，並且在你站立騎行時候找到一個車把前伸的位置。僅僅是車把位置前後2.5~5釐米的調整都會在爬坡時讓你感到巨大的差別。同樣的，坐墊位置的2.5~5釐米的調整帶給你或許是一個50英里長的愉快的旅行，或者是一個僵硬的脖子和酸痛的肩膀。<br/>當你把坐墊從原來的位置向前調整的時候，你的手臂就承擔了更多的體重。但你也可以把車把前伸來獲得更多的力量。場地自行車的坐管角度幾乎是垂直於地面的。這樣的坐墊位置會比旅行者們要求的要向前很多。但我還是要再次強調，一個場地自行車手只會花幾秒鐘時間呆在他的坐墊上。<br/>假如你不能通過前後調整坐墊來獲得你想要的位置，你也用不著失望。各種不同類型的坐墊都會提供滑軌位置比較靠前的版本。或多或少有點補償。也有許多坐杆，他們的坐杆夾會和坐杆本身的中心線有一定的角度。（這也是一種補償吧）<br/>那麼，到底你想在你的車上得到什麼樣的收穫呢？你強調的是速度和加速性能嗎？或者更多的考慮的是騎乘的舒適性和欣賞沿途的風景？你對這些問題的答案決定了你應該如何調整你的坐墊，而不是某個電腦程式或者是某人那充斥了各種圖表的系統。即使你最好的朋友擁有和你完全一樣的身體結構，他如何選擇車輛的尺寸和你也毫無關係。只有你自己清楚騎車的目的，也只有你自己明白如何將一切進行綜合考慮來達到你騎車的目的。<br/>你可能同時擁有一輛短途高速的車子和一台長途的旅行車。因為需要不同的零件使他們能勝任自身的任務，他們的尺寸大小會有所不同。騎手沒有改變，你還是你自己，但你的目的改變了。一台輕快的短途車子會比一台旅行車擁有更低、更為靠前的車把位置，當然它的坐墊位置也應當相應的向前調整。</p><p>關於膝蓋處於踏板軸上方的問題。<br/>大多數的測量系統詳細的描述了一種情況：當踏板軸和曲柄正好連成一線時（通常是踏板在前而曲柄處於水平的位置），你的膝蓋的正好處於踏板軸的正上方，這種描述毫無意義。想像一下，有兩名幾乎一模一樣的車手，其中一名車手的大腿骨比另一名長3釐米，這就意味著他的小腿比另一名短3釐米。這兩位車手的其他身體條件幾乎完全一樣，包括身體的全長，軀幹的長度，臂長和體重。如果把坐墊的位置調整到正好處於踏板軸的正上方，那位大腿骨比較短的騎手就必須把他的坐墊調整到比另一名車手要靠前不到3釐米的位置。當他的大腿骨和踏板都處於水平位置的時候，精確的資料是3釐米，而實際是沒有這種情況的。<br/>但是隨著坐墊的前移大腿骨較短的那位車手就不得不讓他的手臂分擔更多的體重僅僅只是出於那種主觀的讓膝蓋處於踏板軸正上方的理論。那理論毫無意義，重要的是你如何合理的把體重進行分配，而這取決於坐墊相對於曲柄的前後位置。</p><p>車把的位置<br/>接下來我們看看車把的位置應該如何處理。和坐墊一樣，它也取決於你如何使用你的自行車，車把的位置越靠前，你在站立騎行和加速的時候就會獲得更多的力量，並且你的身體也就越符合空氣動力學，高速騎行的穩定性也會更佳。車把越低，你就越能在快速加速的情況下更好的制動。當車把和你身體之間的距離越短（或越高），你就能夠挺直上身並獲得良好的視野。<br/>我喜歡使用一個可調節的把立，它能夠讓我的顧客幾天中在不同的位置花上足夠的時間來下結論。但我們從哪里開始呢？對於使用公路彎把的車手來說，如果你把手放在車把下垂部位。（這個位置應當讓你很容易的觸到刹車把），然後彎曲你的肘部使你的前臂達到水平狀態，在這種情況下，如果你的肘部和前臂的角度形成一個直角，那就是一個好的開端。從這裏開始，試著把你的車把前後調整大約1釐米的距離，找到對你來說是最合適的位置。大多數人會對肘部處於直角的位置感到很舒服，但這不一定適合你。當然，這不是一個讓你長時間騎乘的位置，除非你恰巧處於一個長途的公路下坡路段。<br/>賽車手們通常會把車把高度降低到比坐墊要矮5~8釐米，而旅行者們則把它們調低到同一高度。山地車手們的車把高度通常會比坐墊高度低5釐米，關鍵是要花足夠的時間找到適合自己的位置。如果要把一台旅行車的車把降低到比坐墊低10釐米，你會接受嗎？<br/>我推薦在感覺舒適的情況下，使車把和你之間的距離盡可能的長，高度盡可能的低（舒適性的車子也同樣適用）。</p><p>車把的寬度（公路車和山地車）以及公路車把的下垂角度<br/>有一些品牌的公路車把，他們的設計理念在於從頂部算起的下垂幅度，除非你是一名場地自行車手，你都不會需要一個深度下垂的車把。大多數的車把著重於寬度，很多人在他們車把上的雙手之間的距離與肩同寬的情況下會感到最舒服，這樣他們的手臂在夠得著車把的情況下會大致保持平行。當你選擇不同長度的把立時，試著使用各種不同寬度的車把，從和你的肩寬一樣的開始。最後你會明白哪個對你來說最為合適。</p><p>對坐墊高度的精確調整<br/>當你對車輛各部分的調整感到習慣之後，回頭再檢查一下坐墊的高度。你應該在踏板達到最低點的時候也不會完全繃直你的膝蓋，並且也不用在踏板上晃動你的前腳掌。如果上述情況之一產生了，那你的坐墊高度就太高了。在踏板轉動的過程中，繃直你的膝蓋會限制你流暢的蹬踏的速度，並由於腿長的限制，導致你想把坐墊的後部調整到不那麼有效的位置。通過限制腿的伸長幅度，你能夠更流暢的蹬踏，並獲得更高的頻率。這對你的肌肉和關節都有好處。假如坐墊過低，你的腿部肌肉會感到這點。</p><p>常備的車架尺寸的測量<br/>剛才我們所講到的這些對你到本地的一家車行測量的尺寸有什麼聯繫呢？不同長度的坐管和把立可以構成各種尺寸的組合。這就意味著你可以使用不同尺寸的車架並仍舊配合的很好。<br/>當其他的部件搭配均衡後，一個長的上管會使你的自行車的軸距更長，穩定性更好，並且能更好的吸收震動，當然它也需要一個更短的把立。由於下管（連接五通和頭管的管子）也會隨之變長，因此車架在加速的時候會變軟並產生一些形變，這是長上管車架性能上的一個缺陷。<br/>即使使用同一個把立，在車架上較長的坐管也會抬高你的車把，並給水壺和氣筒留下更多的空間。這也可能使你不能把車把降低到你想要高度。而且更長的坐管也會使車架的上管抬高，並縮短了你橫跨車架時襠部和上管之間的距離。因此，你必須對此慎重考慮。</p><p>後續：<br/>注意到在這裏我們沒有提到任何關於身體測量方面的事情。我也沒有要求你用懸垂法來測量你的膝蓋到地面的距離，或者是要求你前後調整你的車把來使你不能在正面直接看到前軸。<br/>或者是拿你的前臂長度和坐墊前部到車把之間的距離做比較，等等。我的這套方法和大多數人在自行車店擁的那套方法有很大的區別。FIT KITS和其他在市場上使用的系統是建立在對許多不同的車手和他們的車輛進行大量測量的基礎上的，它們可以保證在一定的程度上的，你選擇的結果會比較適合你。<br/>但是讓我們來看看關於兩個車手的例子吧：車手A，和車手B。車手A的上身肌肉很少，但他的腿部肌肉很強壯。車手B的體形和車手A的很相象，可是由於一直在PALPH'S GYM進行戶外工作，使他看起來向個健美運動員。對這兩位車手來說，坐墊的前後位置會有一些輕微的差異。為了獲得同樣的平衡，車手B上身發達的肌肉需要他把坐墊的位置輕微的想後調整。但這並不意味著車手B 就必須要把坐墊後調。他可能還會喜歡比較靠前的位置。只有他自己知道他想要什麼。</p><p>以我自己為例，我在20世紀70年代開始長途旅行。反復實驗多次之後，我得到了一個為我而做的測量系統。（根據這個系統），我可以騎一個世紀而不會疲勞。我也有一輛精確的依照競速車輛設計的自行車。我沒有長高，也沒有變矮，我的胳膊也沒有變長或縮短，但是我的脖子和背在20001年的時候比他們在1975的時候要僵硬的多。當我爬山的時候，較低的車把位置還是很好的。但是在60英里的平地路途上我的脖子就不會象以前那樣舒服了。年紀變大了，我需要一個比較高的車把。<br/>測量我的身體不會不會指出我需要把車把調高。我過去常常在握住公路車把的下部的時候感到很舒服，如果我現在這樣做，那我就幾乎看不到前面的路了。<br/>在場地車和長途旅行車之間找一個折中點是我們大多數人想要的。但我們首先得知道自己的追求是什麼。記住，當你選擇車輛的時候，只有一位專家能幫你。只有你自己知道你在車上的感受。只有你知道應該如何對你自己的騎行進行綜合考慮。你就是那位專家。<br/>順便說幾句，由於我的粗心大意，我經常受到某些人的電子郵件。他們告訴我他們讀了我的文章，很喜歡，但有一個問題。然後他們告訴我自己的腿有多長，胳膊有多長，軀幹又有多長，隨之告訴我某家自行車行想要向他們出售一輛特定的車子，想要我告訴他們這台車子是否適合他們。我的第一反映就是擔心我是否把文章寫清楚了，或者是他們讀了它但是不理解，或者是他們根本就沒有讀。我有時會回過頭複讀我的文章，確定我把觀點表達的很清楚了。可究竟為什麼那些人不清楚，我就不得而知了。</p><p>於是我得再強調一遍，我不知道那台車子是否適合你。即使我知道車子和你的身體的每一個細節，我也不能告訴你它是否適合你。所以別在寫信問我這些我不可能回答的問題。請再讀一遍文章。<br/>如果你需要那些關於你的自行車的權威數字，那麼就去那些有KIT FIT或者其他類似的系統的車行吧。給他們錢，找他們說的做。有些人就得照章辦事，但是我不想告訴你要做什麼。我寧願提供你們需要的知識，然後你們自己去尋找。有了這些知識，我想你們自己會比那些要你們付錢的專家幹得更好。<br/>順便說兩句，我是一個自行車商人，不是醫生。如果你的膝蓋或者脖子或者手腕或者背因為根據我的文章所提供的資訊組裝的自行車而受傷，那麼我想你可以控告我，但是別指望我呢能對你的傷勢作出診斷。去看醫生吧，然後在控告我。<br/>請不要誤解我。如果我寫了什麼你不能理解的東西，或者你認為我遺漏了某些關於車輛尺寸選擇的觀點，請讓我知道。為了回答讀者的問題，這篇文章已經被下載了很多次了。那麼，就請繼續來信吧。<br/></p><p style="TEXT-ALIGN: center"><img src="http://www.bigcomic.com/blog/upload/52563262_tn.jpg" style="DISPLAY: inline; WIDTH: 522px; HEIGHT: 208px" title="52563262.gif" height="208" width="522" alt="52563262.gif" id="urn:zoundry:jid:52563262.gif"/></p><p><br/></p><p style="TEXT-ALIGN: left"><span class="logtext"><span id="c_391763">日前整理了一些身高對應車架尺寸的資料，在此提供各位參考。整個比較下來，都與一些環法車手的愛駒幾乎接近。不管是傳統或是壓縮車架，原則上以＊上管水平C-C＊位置為選擇依據。尺寸對應如下：<br/>身高/上管水平C-C<br/>166cm/49cm<br/>167cm/49.5cm<br/>168cm/50cm<br/>169cm/50.5cm<br/>170cm/51cm<br/>171cm/51.5cm (Eddy Merckx MC EWEN 171cm/51.5cm)<br/>172cm/52cm<br/>173cm/52.5cm<br/>174cm/53cm<br/>175cm/53.5cm (GIANT Vinokourov,Colnago RASMUSSEN175cm/53.5cm)<br/>176cm/54cm<br/>177cm/54.5cm ( TREK Lance Armstrong 178cm/54.5cm)<br/>178cm/55cm ( BMC Landis Floyd 178cm/55cm )<br/>179cm/55.5cm<br/>180cm/56cm<br/>181cm/56.5cm ( CERVELO IVAN BASSO, JULICH Bobby, 181cm/56.5cm)<br/>182cm/57cm (GIANT Jan Ullrich 183cm/57cm)<br/>183cm/57.5cm<br/>184cm/58cm<br/>185cm/58.5cm<br/>186cm/59cm<br/>187cm/59.5cm<br/>至於stem長度配置大約如下：<br/>上管水平C-C/stem長度<br/>49.5cm~52cm/9cm<br/>52.5cm~54cm/9~10cm<br/>54.5cm~56cm/10~11cm<br/>56.5cm~58cm/11~12cm<br/>58.5cm~60cm/12~13cm<br/>(以上僅供參考，實際依個人騎乘方式調整)<br/>其實在身高對應車架尺寸上是可以±0.5cm.基本上是可以有個小range.以應付各廠家尺寸的不足，再以龍頭&amp;坐墊微調達到標準要求。<br/>至於車架尺寸差個1cm以上，對龜毛要求標準的人來說，已明顯不適合。。至於車頭高度依個人而異去調整！</span></span></p><br/>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/161.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=161</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=161&amp;key=eb7e7f35</trackback:ping></item><item><title>负载均衡路由器</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/159.html</link><pubDate>Fri, 31 Aug 2007 07:06:32 +0800</pubDate><guid>http://blog.bigcomic.com/post/159.html</guid><description><![CDATA[<p>侠诺 FVR9208<br/><a href="http://detail.zol.com.cn/92/91875/price.shtml">http://detail.zol.com.cn/92/91875/price.shtml</a> 7600<br/>普联(TP-LINK)</p><p>TL-R488<br/>TL-R488T<br/><a href="http://www.buysou.com/product/spec/69105.htm">http://www.buysou.com/product/spec/69105.htm</a> 3950</p><p>AboCom MH2000<br/><a href="http://guide.it168.com/pages/15333.shtml">http://guide.it168.com/pages/15333.shtml</a> 15900<br/><a href="http://product.yesky.com/product/161/161968/param.shtml">http://product.yesky.com/product/161/161968/param.shtml</a></p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/159.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=159</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=159&amp;key=364bf875</trackback:ping></item><item><title>SQL SERVER安装: 以前的某个程序安装已在安装计算机上创建挂起的文件操作 </title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/158.html</link><pubDate>Tue, 28 Aug 2007 14:00:13 +0800</pubDate><guid>http://blog.bigcomic.com/post/158.html</guid><description><![CDATA[解决：以前的某个安装程序已在安装计算机上创建挂起的文件操作<br/>安装SQL Server 遇到错误提示：<br/><br/>以前的某个程序安装已在安装计算机上创建挂起的文件操作。运行安装程序之前必须重新启动计算机!。<br/><br/>解决方法：<br/><br/>打开注册表编辑器，在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager中找到PendingFileRenameOperations项目，清空它的内容。这样就可以清除安装暂挂项目。<br/><br/>如果在之前确实并无安装任何软件，那就可能是 3721 之类的流氓软件修改了该项设置。<br/><br/>这个设置可能影响到 MS SQL Server 2000 和 MySQL 5.0 的安装。<br/><br/>若 MySQL 5.0 安装配置时提示注册服务失败，除了要在 添加/删除应用程序 中卸载 MySQL 5，还要手工删除所有与 MySQL 设置信息、数据库有关的文件夹和文件，并且通过安装 MySQL 5 后的配置向导在配置新实例之前先 Remove 掉所有已注册（失败）的系统服务。然后再配置 MySQL 5.0 新实例。<br/>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/158.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=158</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=158&amp;key=5ef4b6ad</trackback:ping></item><item><title>双绞线网线线序解析</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/157.html</link><pubDate>Mon, 27 Aug 2007 05:05:37 +0800</pubDate><guid>http://blog.bigcomic.com/post/157.html</guid><description><![CDATA[<p>局域网就是将单独的微机或终端，利用网络相互连接起来，遵循一定的协议，进行信息交换，实现资源共享。网线常用的有：双绞线、同轴电缆、光纤等。双绞线可按其是否外加金属网丝套的屏蔽层而区分为屏蔽双绞线（STP）和非屏蔽双绞线（UTP）。从性价比和可维护性出发，大多数局域网使用非屏蔽双绞线（UTP-Unshielded Twisted pair） 作为布线的传输介质来组网。<br />UTP网线由一定长度的双绞线和RJ45水晶头组成<br />双绞线由8根不同颜色的线分成4对绞合在一起，成对扭绞的作用是尽可能减少电磁辐射与外部电磁干扰的影响。在EIA／TIA－568标准中，将双绞线按电气特性区分为：<br />三类、四类、五类线。网络中最常用的是三类线和五类线，目前已有六类以上的。<br />做好的网线要将RJ45水晶头接入网卡或HUB等网络设备的RJ45插座内。相应地RJ45插头座也区分为三类或五类电气特性。RJ45水晶头由金属片和塑料构成，制作网线所需要的RJ一45水晶接头前端有8个凹僧，简称&quot;SE&quot;（Position，位置）。<br />凹槽内的金属触点共有 8个，简称&quot;8C&quot;（ Contact，触点），因此业界对此有&quot;8P8C&quot;的别称。特别需要注意的是RJ45水晶头引脚序号，当金属片面对我们的时候从左至右引脚序号是1～8，序号对于网络连线菲常重要，不能搞错。<br />EIA／TIA的布线标准中规定了两种双绞线的线序568A与568B。<br />568A标准：<br />绿白--1，绿--2，橙白--3，蓝--4，蓝白--5，橙--6，棕白--7，棕--8<br />568B标准：<br />橙白--1，橙--2，绿白--3，蓝--4，蓝白--5， 绿--6，棕白--7，棕--8<br />（&quot;橙白&quot;是指浅橙色，或者白线上有橙色的色点或色条的线缆，绿白、棕白、蓝白亦同）。<br />双绞线的顺序与RJ45头的引脚序号要-一对应。<br />为了保持最佳的兼容性，普遍采用EIA／TIA 568B标准来制作网线。注意：在整个网络布线中应该只采用一种网线标准。如果标准不统一，几个人共同工作时准会乱套；更严重的是施工过程中一旦出现线缆差错，在成捆的线缆中是很难查找和剔除的。笔者强烈建议统一采用568B标准。<br />事实上10M以太网的网线只使用 1、2、3、6编号的芯线传递数据，即1、2用于发送，3、6用于接收，按颜色来说：橙白、橙两条用于发送；绿白、绿两条用于接收；4、5，7、8是双向线。<br />100M和1000M网卡需要使用四对线，即8根芯线全部用于传递数据。由于10M网卡能够使用按 100M方式制作的网线；而且双绞线又提供有四对线，所以日常生活中不再区分，10M网卡一般也按 100M方式制作网线。<br />另外，根据网线两端连接网络设备的不同，网线又分为直通线（平行线）和交叉线两种。直通线（平行线）就是按前面介绍的568A标准或568B标准制作的网线。而交叉线的线序在直通线的基础上做了一点改变：就是在线缆的一端把1和3对调，2和6对调。即交叉线的一端保持原样（直通线序）不变，在另一端把1和3对调，2和6对调。<br />交叉线两端的线序如下：<br />一端(不变) 另一端(对调两根)<br />橙白 1 3 绿白<br />橙 2 6 绿<br />绿白 3 1 橙白<br />蓝 4 4 蓝<br />蓝白 5 5 蓝白<br />绿 6 2 橙<br />棕白 7 7 棕白<br />棕 8 8 棕</p><p><br />直通线用于连接:<br />1.主机和switch/hub;<br />2.router和switch/hub</p><p>交叉线用于连接:<br />1.switch和switch;<br />2.主机和主机;<br />3.hub和hub;<br />4.hub和switch;<br />5.主机和router直连</p><p>在实践中，一般可以这么理解：<br />1、同种类型设备之间使用交叉线连接，不同类型设备之间使用直通线连接；<br />2、路由器和PC属于DTE类型设备，交换机和HUB属于DCE类型设备；<br />3、RJ45网络接头做法一般有568A和568B两种标准做法，按同一标准即直通线，不同标准即交叉线。<br />不管如何接线，最后完成后用RJ-45测线仪测试时，8个指示灯都应依次闪烁。<br /></p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/157.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=157</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=157&amp;key=9ae9bd6e</trackback:ping></item><item><title>VLAN间路由</title><author>pencat@bigfoot.com (pencat)</author><link>http://blog.bigcomic.com/post/156.html</link><pubDate>Mon, 27 Aug 2007 04:42:48 +0800</pubDate><guid>http://blog.bigcomic.com/post/156.html</guid><description><![CDATA[<p>　　<strong>VLAN间路由的必要性</strong></p><p>　　根据目前为止学习的知识，我们已经知道两台计算机即使连接在同一台交换机上，只要所属的VLAN不同就无法直接通信。接下来我们将要学习的就是如何在不同的VLAN间进行路由，使分属不同VLAN的主机能够互相通信。</p><p>　　首先，先来复习一下为什么不同VLAN间不通过路由就无法通信。在LAN内的通信，必须在数据帧头中指定通信目标的MAC地址。而为了获取MAC地址，TCP/IP协议下使用的是ARP。ARP解析MAC地址的方法，则是通过广播。也就是说，如果广播报文无法到达，那么就无从解析MAC地址，亦即无法直接通信。</p><p>　　计算机分属不同的VLAN，也就意味着分属不同的广播域，自然收不到彼此的广播报文。因此，属于不同VLAN的计算机之间无法直接互相通信。为了能够在VLAN间通信，需要利用OSI参照模型中更高一层--网络层的信息（IP地址）来进行路由。关于路由的具体内容，以后有机会再详细解说吧。</p><p>　　路由功能，一般主要由路由器提供。但在今天的局域网里，我们也经常利用带有路由功能的交换机--三层交换机（Layer 3 Switch）来实现。接下来就让我们分别看看使用路由器和三层交换机进行VLAN间路由时的情况。</p><p>　　使用路由器进行VLAN间路由</p><p>　　在使用路由器进行VLAN间路由时，与构建横跨多台交换机的VLAN时的情况类似，我们还是会遇到&quot;该如何连接路由器与交换机&quot;这个问题。路由器和交换机的接线方式，大致有以下两种：</p><p>　　l 将路由器与交换机上的每个VLAN分别连接</p><p>　　l 不论VLAN有多少个，路由器与交换机都只用一条网线连接</p><p>　　最容易想到的，当然还是&quot;把路由器和交换机以VLAN为单位分别用网线连接&quot;了。将交换机上用于和路由器互联的每个端口设为访问链接，然后分别用网线与路由器上的独立端口互联。如下图所示，交换机上有2个VLAN，那么就需要在交换机上预留2个端口用于与路由器互联；路由器上同样需要有2个端口；两者之间用2条网线分别连接。<br /><img id="urn:zoundry:jid:vlan3332_3.JPG" title="vlan3332_3.JPG" style="DISPLAY: block; WIDTH: 512px; HEIGHT: 384px; TEXT-ALIGN: center" height="384" alt="vlan3332_3.JPG" width="512" src="http://www.bigcomic.com/blog/upload/vlan3332_3_tn.jpg" /><br /></p><p>　　如果采用这个办法，大家应该不难想象它的扩展性很成问题。每增加一个新的VLAN，都需要消耗路由器的端口和交换机上的访问链接，而且还需要重新布设一条网线。而路由器，通常不会带有太多LAN接口的。新建VLAN时，为了对应增加的VLAN所需的端口，就必须将路由器升级成带有多个LAN接口的高端产品，这部分成本、还有重新布线所带来的开销，都使得这种接线法成为一种不受欢迎的办法。</p><p>　　那么，第二种办法&quot;不论VLAN数目多少，都只用一条网线连接路由器与交换机&quot;呢？当使用一条网线连接路由器与交换机、进行VLAN间路由时，需要用到汇聚链接。</p><p>　　具体实现过程为：首先将用于连接路由器的交换机端口设为汇聚链接，而路由器上的端口也必须支持汇聚链路。双方用于汇聚链路的协议自然也必须相同。接着在路由器上定义对应各个VLAN的&quot;子接口（Sub Interface）&quot;。尽管实际与交换机连接的物理端口只有一个，但在理论上我们可以把它分割为多个虚拟端口。</p><p>　　VLAN将交换机从逻辑上分割成了多台，因而用于VLAN间路由的路由器，也必须拥有分别对应各个VLAN的虚拟接口。</p><p style="TEXT-ALIGN: center"><img id="urn:zoundry:jid:vlan3332_4.JPG" title="vlan3332_4.JPG" style="DISPLAY: inline; WIDTH: 512px; HEIGHT: 384px" height="384" alt="vlan3332_4.JPG" width="512" src="http://www.bigcomic.com/blog/upload/vlan3332_4_tn.jpg" /></p><p>　　采用这种方法的话，即使之后在交换机上新建VLAN，仍只需要一条网线连接交换机和路由器。用户只需要在路由器上新设一个对应新VLAN的子接口就可以了。与前面的方法相比，扩展性要强得多，也不用担心需要升级LAN接口数不足的路由器或是重新布线。</p>]]></description><category>文档</category><comments>http://blog.bigcomic.com/post/156.html#comment</comments><wfw:comment>http://blog.bigcomic.com/</wfw:comment><wfw:commentRss>http://blog.bigcomic.com/feed.asp?cmt=156</wfw:commentRss><trackback:ping>http://blog.bigcomic.com/cmd.asp?act=tb&amp;id=156&amp;key=72965af7</trackback:ping></item></channel></rss>
