??xml version="1.0" encoding="utf-8" standalone="yes"?> 李明Q“是不是升官了,很兴奋,以前你当E序员的时候,好象都不会这样?br />陈默Q“当E序员只要做好自q事情Q烦恼就多了,加上我也很聪明,所以做E序员的工作很L啊,刚被认ؓ为项目经理的时候,只兴奋了不到一个星期,后面,唉?/p>
李明Q“差别会很大吗??br />陈默Q“刚开始时认ؓQ项目经理应该很好当Q我以前怎么做的p求别人怎么做就行了Q后来做的过E才发现Q那Ҏp不通?/p>
李明Q“很多h都是q么L的啊?br />陈默Q“我开始做理的时候,发现的第一个问题是Q每个程序员都觉得自己是聪明人,p我自׃P所以当我要求他们象我那样去做的时候,除了三个刚毕业的学生会去执行外,其他人根本就不听Q他们说我都做了好几q了Q也没有发现我的Ҏ比你的差Q我做完p了,你别那么多?/p>
李明Q“这样也没有什么啊QQ务能完成好了?br />陈默Q“是啊,开始我也是q么惻I慢慢的就发现问题很多?/p>
李明Q“一般的软g开发都有点象黑盒,彼此之间能衔接v来就行了?br />陈默Q“说h是这P可实际情况就有很多出乎意料的地方。D个例子,我有个程序员Q小梅,是你见q的那个湖北的小丫头Q做E序员都没有的说的,三年来都做的很不错,几个月前我们开始做一个银行的国债项目,Ҏ主要E序员,因ؓ财政部马上要推出储蓄国债,我们公司事先知道Q所以先帮一个客h前设计这个YӞ计划在元旦时间完成,和胦攉K推出的时间基本一致。本来我计划的好好的Q结果这个小丫头l我来了一下子?/p>
李明Q“她不是和你Uh关系也不错,怎么会给你来一下子Q看不出来啊?br />陈默Q“是啊,所以我开始就很放心的把主要Q务交l她Q谁知道二个月前她告诉我说要请假Q如果请不了假就辞职?/p>
李明Q“是不是要求加薪Q?br />陈默Q“她不是那样的hQ她告诉我这L事情Q二个月前她不小心有了,本来Z工作惛_做掉Q医生检查的时候,和她_你的w体状况不好Q这ơ不要,以后可能很难怀上,而且q一胎还要静M胎,不然也有危险Q她老公和和奚w是独生子奻I双方的家镉K要她把孩子生下来Q你说我怎么办,要是关系普通我把q事情推lh事部门去处理Q就是关pM错,所以,我就只好帮她x|,把自q郁闷歅R?/p>
李明Q“后来你怎么搞定的?br />陈默Q“想Ҏ完就了Q就按黑盒子的方法处理,l果被老板训了一,老板说这么重要的软gQ你׃怕在q行q程出点意外Q每个错误可能造成很多金钱的损失,我们做的是金融的pȝQ不是一般的信息理pȝQ一点的错误都可能造成不可估量的损失。我一听就MQ那怎么办啊Q?/p>
李明Q“确实是很郁L?br />陈默Q“我头痛了一个晚上,最后没有办法,只能是我自己重新写过Q每天只?个小Ӟ赶了一个多月,才基本搞定,没有影响q度。?/p>
李明Q“你老兄q是有两下子吗?br />陈默Q“可是你知道我付出多惨重的代价?/p>
李明Q“不惨啊Q才一个多月的辛苦啊,奖金可是大把的哦?br />陈默Q“结果是我得了颈锥劳损,l常要摇一下脖子,喀嚓一下才会觉得舒服一点,同事们都说我吃摇头丸q量Q居然白天还在摇。。。?/p>
李明Q“是有点惨,不够也ȝ完成了?br />陈默Q“唉Q?/p>
。。。。。。。。。。?/p>
陈默Q“我的项目终于结束了Q晚上请你喝一杯?br />李明Q“你舒服了,我可完蛋了? 陈默Q“你的黑盒子Ҏ不是一直很用嘛,再说Q你的程序员都是LQ也不用保胎Q有什么问题呢?br />李明Q“唉Q有个程序员C? 陈默Q“走了就CQ有什么好Ҏ的?br />李明Q“客L盘坏了Q我们去重装pȝQ我把所有的源程序都重新~译了一下,l果出大事情了。? 陈默Q“重新编译很正常Q我们也l常q样做,怎么会出大事情呢Q?br />李明Q“那家伙留下来的源程序与之前的运行程序不一_也就是说他给我们留下的不是原来运行的那个Q他做了手脚。? 陈默Q“这么恶劣,可以告他Q?br />李明Q“外地的员工Q现在h也不知道跑那里去了,之前的运行程序我们也没有备䆾Q告他也没有证据啊,要是他一口咬定最后移交的是q样的东西,我们都认可了他才走的Q我们也无话可说。? 陈默Q“项目经理很隑ֽ啊,q不如做E序员轻村֑?br />李明Q“是啊,可是谁不惌位高一点,钱多赚一点,象我们这行吃青春饭的Q真很悲哀。? 陈默Q“经历过q些事情以来Q我在惻IN没有好的Ҏ来管理吗Q?br />李明Q“有啊,引进CMM啊? 陈默Q“这谁都会想的到Q可是费用太高,而且效率也不高,Ҏ们这U不大不的软g公司来说Q不是很合适的Q?br />李明Q“那在开发规划上Q以及注释上做的详细一炏V? 陈默Q“这也只能改q,无法解决Ҏ问题。?br />李明Q“我们上|去找找看,有没有什么东西可以启发或者借用的。? 陈默Q“好啊,以后我们也不要老扯q些烦恼的事情,我们q是只能多想惌决问题的ҎQ不然以后真不知道怎么办??br />李明Q“是的。? 。。。。。。。。?/p>
陈默Q“李兄,我有一个好消息告诉你,晚上见一面如何??br />李明Q“好啊, 我刚好也有一个好消息要告诉你。? 陈默Q“是我先_q是你先_你要告诉我什么。?br />李明Q“我先说吧,我几天前上网Q找C一个工P可以把开发效率提高好几倍,更重要的是可以辅助管理各U开发的资源Q编码的实现都很化、标准化Q我准备l老板推荐一下。? 陈默Q“哦Q是q样的呀Q我老板前几天找到我Q说他买了一套开发工P让我以后按照q套工具来开发YӞ他说他不想以后看到我在面前摇头晃脑的。看了头晕。?br />李明Q“是什么工具啊Q? 陈默Q“国内最新的产品Q网航Web Studio开发^台?br />李明Q“等{。不会这么y吧,我要说的也是q个东西也,我最q比较了好多工具Q好不容易才分出优劣Q你老板真有眼光啊。? 陈默Q“我老板做了近二十q的软gQ还是不错的Q和IBM{公怹来往密切Q以前想买国外的软gQ可是几十万的h位,实在下不了这个决心,国外的品做应用Q对国内的客户也不容易接受,不够通俗吧。所以就一直没有买Q这套国内的产品Qh位还不到十万Q很划算的,功能比国外的产品q好。?br />李明Q“功能我是都分析q了Q没的说的,本来我还以ؓ要几十万一套呢Q没有想到还q么便宜Q是要给老板一下,C套,不知道他肯不肯花q个钱? 陈默Q“应该没有问题吧。你们做的Y件v码也都是几十万一套的Q成本也都要二三十万吧,如果用这套工h做,一个项目就节省一半的费用Q工L钱就出来Q再加上软g资源理做的很规范,对该目来的升U,产品攚w都很方便,也不怕程序员的流动或者做手脚。多好啊Q你老板又不是傻瓜,他会不懂q些道理吗??br />李明Q“说的也是啊。我明天去说。这东西可靠吗?? 陈默Q“可靠,我查q他的一些案例,有一些是金融的,我还打电话到q些应用单位去询问过Q反映都不错Q就是目前的名气q不大。?br />李明Q“东西好Q名气是q早的事情,我争取用上,也给我们那些同行朋友们推荐一下,以后我们喝酒的时间就多一些了。? 陈默Q“应该是的,来,q一杯。?br />李明Q“干杯!? fromQ?a >http://community.csdn.net/Expert/topic/5159/5159226.xml?temp=.4152338 按期成功完成一个项目的关键在于U极的计划和合理的时间、资源管理。本文关于项目管理的q些会帮助您计划好下一个项目,保在预范围内以高质量水^按时完成?/p>
也许您曾听说q“时不待我。”这虽然只是陈词滥调Q但q不意味着它一点可取之处也没有Q尤其是在邻qIT目截止日期的情况下。变化无常的旉计划Q或高估或低估时间期限,也就是所谓的“需求渐变问题”,以及H如其来的员工生病事件或供应p|{等——这些都是会D您的IT目出错Q或可能出错Q的原因?/p>
因ؓ旉是当今社会衡量效率的一般标准,所以因q些事由D的计划推q、g误都会最l带来相当规模的财损失Q除了名誉受到损害之外)?/p>
有没有解军_法呢Q当然有Q合理的计划Q良好的执行Q考虑到可能会出现的困难,q些一定能保目成功执行q完成。大部分目l理清楚q些Qƈ花大量时间制定项目时间表和交付时限表。然而,常常q导致他们出错的是,他们没能认识到项目计划是一个持l性的zdQ必d目q展周期中积极地、持l地发生Q而不是收到客户预支款后便告一D落?/p>
在本文中Q我提Z些徏议,帮助您有效地q行下个目的计划,q确保在预算前提下以高质量水qx时完成项目?/p>
问题 首先Q让我们看看D目延误的几个原因: 野心q大的估计和不恰当的d评估Q往往Q一个项目团队对于完成既定Q务不能做出恰当的旉和精力的估算Q而制定出q于U极乐观的时间计划。客户带来的压力也会q一个团队去试在本已有限的旉内完成过多的d——这是最l会D最l品生质量风险的自我挫|战略? 不合理的目规模Q往往Q对于一个团队所l定的时限,一些项目过于庞大。管理h员(或客P有时在未实际分析目可行性的情况下,便尝试无理地把尽可能多的Ҏ和发展d压羃在一赗? d分派不明:有时QQ务没有明分工,团队成员角色不明导致成员间的生误解? ~Z资源Q“这个项目需要五名开发h员,但是我们只有四名。没关系Q我们会处理好的。”听h熟悉吗?如果是,那么p清楚q样是行不通的——一个需要五名成员的目Q如果少了一位,q不能如期完成。另外一U类似情冉|一个项目在开始之时有着合适的成员数量Q但在项目过E中Q一些成员被“分z䏀去参加其他的项目(通常q是因ؓ某些高层领导认ؓ他们在资源分配上比项目经理懂得更多)? 基础讑֤不完善或遭破坏:一些项目的延误常常是因为对于一个项目的成功完成必不可少的基讑֤——如g、Y件、工兗文档等——在最需要它们的时候无法得到或不能正常q行?br />? 然而,一切ƈ非只剩黯淡和无望。以下的措施会~和q些问题q保证项目按照计划运行和如期完成?/p>
详细分析要求Q仔l理解与目有关的各个方面,具体到最l小的要炏V对于模p不清的斚w要提出问题直x楚理解。最后,雇䄦专业人员归类整理业务要求Q操作细节和设计要求。小心需求的渐变Q一不小心,它便会摧毁您所做的一切努力。如果有必要Q要大胆地羃项目规模或避免d计划外的新方案,因ؓq必定需要更高要求的旉整合? 合理配置可利用资源:按照要求配置可利用资源,保_的h员来完成工作。在目q行启动之前保目利执行的各U基设施——硬件、Y件、h力资源、工兗文本信息等——都已到位? q行培训和知识迁U:如果有培训,培训也该作是项目时限内的一部分。不要把培训当作员工工作旉以外的Q务,而应该把其列入项目计划和预算之内? 估算与分配:l每位组员分z角色和dQ确保每Q务具有明的负责人。运用项目管理工具和甘特图表记录每位成员的Q务以及每Q务开始和完成的日期。如果在d责Q分派制这一环节上失败会D责Q重叠、精力无谓重复、时间浪费和产品质量低下? 工作d模块化:把每主要工作Q务划分ؓ几项子Q务,直至每项工作都是一个完整的个体Q与其他工作互相独立。以逻辑序整理排列Q然后以发生先后为序开始执行最l小的一工作Q务? 避免q多会议Q策划关于项目状态的讨论会,或在以需要ؓ基础的前提下卛_Ҏ问题所在。冗长的、无休止的、没有明议E、明结果的会议只是费旉? 做好记录Q记录项目的成功与失败。这一点很重要Q这会成为其他项目中相应工作d的历史参考信息。用项目纪录板以图表的形式在更高层ơ综观项目,更好地衡量项目进E。在每一步重大{折时寚w目进行检查鉴定,q依此更新项目纪录板? 认识全天候发展模式:如果有一U全天候发展模式(一U在全球范围内持l不断进行的工程作业环境Q,保在不同部门团队成员间和跨国团队成员间明确沟通,避免误会。定期做好协调工作以避免不必要问题的出现? 逐步上报问题Q当问题出现Ӟ要第一旉报告理层,q尽可能多地制定解决Ҏ。在事态严重到无法补救以前Q要试各种弥补办法便是您最后需要做的一件事?
李明Q“那你怎么办??br />陈默Q“只好我自己接她的工作,要命的是她写的很多程序我居然M懂,她也没有写很仔细的说明,那天Ҏ觉n体不好,匆匆回MQ之后就没有办法再过来,我只好猜、猜、猜Q有一天我q跑到她安的闺房去询问Q唉Q别提有多难受呢Q还不如自己重新写,可算时_实在是来不及?/p>
大家看看有什么启发?或者有什么感惻I
~Z风险理pȝQ有些团队盲目自信,怿他们可以在最后一U拯救一个计划,怿所有危险可以放到第二天的会议上得到解决。这是个不切实际的想法。所有项目都不可避免的会有问题存在;M一个问题都可能摧毁整个计划Qə目不堪重击而失败。如果这些问题不能够被明查出,q在良好的基上不能提前解冻I那么l果只会往更坏的方向发展?
解决ҎQ?0点徏议)
识别风险Q确认潜在风险和准备H发事g预案以备不时之需。制定后备计划以备在H发情况和h力方案失败之时如期完成;q种“B计划”方案是在项目未按计划成功进行情况下的支持性系l?
必须清楚Q按期成功地完成目关键在于前期计划和合理的旉Q资源管理。采U以上徏议,您的目会如期完成Qƈ辑ֈ目标。祝您好q!
lgQ简单的讄Ҏ如下Q?br />
jsp (gbk) ----> java(ISO-8859-1) -------> mysql(gbk)
转换
q样讄之后Q还有一U情况会出现qQ当你在jsp端提交一个idP然后在java处理端通过id号得到数据库中的gbkQ汉字)数据Q这是就会出Cؕ码,因ؓjava处理的是ISO-8859-1Q你在java到mysql中有了一个ISO-8859-1到gbk的{换,而这些数据本w就是ISO-8859-1,所以{换后出现问题了?br />解决办法Q将在java中处理的gbk数据转换为ISO-8859-1卛_?br />
MQ在jspQjavaQmysql三者之间的~码方式必须l一Q不能错误的转换或者不转换?img src ="http://m.tkk7.com/soochow_hhb/aggbug/78845.html" width = "1" height = "1" />
在实际的pȝ中,要多个类共同协作来完成某一Q务,一般称为复合。在pȝ的设计过E中Q耦合是不可避免的Q是必须的,但是它会带来以下问题Q?br />Q-难以试Q看下面的两个类Q?br />KnightOfTheRoundTable
|
| new
V
HolyGrailQuest
在KnightOfTheRoundTablecM使用了HolyGrailQuestc,q且可能使用不同的QuestcR这两个cȝ功能是骑士去执行不同的Q务,HolyGrail只是代表了一UQ务。这U通过国new的方式,使得knight和quest两个cȝ密的耦合在一赗设计完成后做单元测试,看下面的代码Q?br />KnightOfTheRoundTable knight = new KnightOfTheRoundTable("Bedivere");
HolyGrail grail = knight.embarkOnQuery();
assertNotNull(grail);
assertTrue(grail.isHoly());
在测试KnightOfTheRoundTablecȝ时候,间接的测试了HolyGrailQuestc,但是对于HolyGrailQuestcȝ情况q没有很昑ּ的测试,所以用了最后的两行代码来测试,昑־很笨拙。不知道是否试了所有可能的情况?br />Q-难以l护
如果以后修改了代码,或者增加了/改变了knight的Q务,代码必须改动Q测试代码也要改动,q且改动一个地方,可能会媄响到其他很多地方Qؓ日后的维护工作带来了ȝ
Q-紧耦合
提示Q这U模式引L问题Q主要是因ؓ紧耦合所_所以要解决q种问题的首要方案就是解耦合Q但如何来解耦合呢?Ll看Q?br />Q?Q解耦合——通过接口interface来实?br />因ؓ骑士可能执行不同的Q务,也有不同U类的骑士,所以我们可以将d和骑士抽象ؓ接口Q将具体的实现隐藏在接口之下Q这样就不必在knightcM通过昄?HolyGrailQuest quest = new HolyGrailQuest ()q样的语句来创徏Quest对象Q而可以通过接口Quest quest Q?new HolyGrailQuest()来实现。这样就形成了如下的cdQ?br />
q样Q虽然用了接口Q得层ơ分明,通过接口Quest来实现探险,但是q是只能从事一U探险Q务,而如何才能让骑士从事M一UQ务呢Q请l箋看!
Q?Q给予与获得
骑士执行探险d有两U方式:
W一、让骑士d获得探险dQ前面的实现方式属于q类Q通过new来实玎ͼ
W二Q让骑士被动的获得Q务,即给予骑士某Ҏ险Q务,q样p决了上面的问题(让骑士可以从事Q何一UQ务,只要l他们分配即可)?br />实际实现的方式很单,看如下代码:
public void setQuest(Quest quest){
this.quest = quest;
}
单的代码实现了方式的改变Q这LKnightOfTheRoundTablecM入Q何的QuestdQ都可以接受了?br />到这里可以很明显的看出来Q我们将以前的new方式Q翻转过来,即不是让d获得依赖c,而是被动的获得依赖类Q这是IoC的核心,实际Fowler说得依赖注入也很贴切Q即向类中“注入”它依赖的其他类?br />
好了Q到q里Q应该知道了IoC的基本概念了吧,也知道了IoC的基本功能了吧?br />要想更深入的了解Q请x我的文章?/span>
创业到底需要具备什么条ӞҎ而言Q完全是一U冲动,d九月份,我们两个接到一个项目,非常的兴奋,有天需求方问我怎么出票Q我怎么攉的问题?U在心中的创业的火焰一下子燃烧了,和同学一拍即合,注册公司。当初的x是多么的单啊Q?/span>
我现在觉得创业需要几个条Ӟ勇气、愿景、团队和技术。勇气是前提Q必迈出第一步;愿景是目标,公司要做什么,要在哪个斚w发展Q必要明确Q团队对于创业初期是非常重要的,在创业初期由于经验不I可能会走很多的弯路,也会到很多的困难,一个勇于开拓,团结一心的团队对于公司的发展v着臛_重要的作用;对于U技型公司来_技术就是你的法宝,一定要在某一Ҏ术上能够深入下去Q能够独树一帜,在公司的发展q程中一定要能沉淀出有自己特色的核心技术?/span>
对于创业者来_如何q出W一步是勇气的问题,特别对于我们在校大学生而言Q虽然现在有很多呼声鼓励大学生创业,但是具体的配套措施和孵化措施q很不到位,只有一个想法、点子也是不行的Q还需要启动资金,需要持l的业务。我们是q运的,通过我们的努力,利的完成了我们的第一个项目,利的得C我们的启动资金。虽然创业的初衷是冲动,但是我们已经q出了坚实的W一步?/span>
创业当然要有
?/span>
?/span>
?/span>
Q当初的冲动q不能保证将来的成功Q有了一点的U篏之后Q就要好好确定一下自q创业方向了(当然Q大部分是最初都有的Q,也就是公司的愿景Q就和一个h的目标一P要在某段时期内作Z么东西,来要达C么程度必L。这是最最关键的了Qƈ且要定位好,不能看到别h在哪个方面赚׃Q自己就跟着dQ从而迷׃自己的方向。我们在拿到W一W启动资金之后,q定了公司发展的两条主U,W一是利用我们的技术和l验为公司提供高效的信息pȝQ第二是我们的长q目标,是Z业提供灵zR方ѝ快L多媒体通信服务。第一条线在前期资金短~的情况下,为第二条U上的品研发提供资金支持?/span>
团队是初期创业公司的灵魂Q如果没有一支能够吃苦、高效、有毅力的团队,对于公司初期的发展是很不利的。在创业的过E中Q特别是对于W一ơ创业者来_会遇到很多以前根本想不到的困难,有时也会遇到一点资金都没有的状况,如何从前期的困难中走出,从而开辟一条生存之路,是首先要考虑的问题。因为我们两个都是学生,创业的初hq青人的冲动Q对很多问题的看法简单话Q遇C很多问题和困难。这里首先要感谢吴中区科技创业园对我们的支持和鼓励Q尤其是pMQl了我们很大的鼓励,努力帮助我们走出困境。当她看到我们正在研发的一个有兛_媒体|络通信的Y件时Q立即鼓励我们去x市科技据的U技目Qƈ且邀请了U技局的一些领导和专家来听取我们的目汇报Q我们从中学C很多东西Qƈ且更重要的是得到很多领导和专家的鼓励和支持,通过U技园的U极推荐Q我们获得了很多重要的机会?/span>
技术对于科技型企业来说是生存之本Q在创业初期Q不可能有很多h才,也不可能搞资本运作,也很难拉到社会上的投资,所以唯有依靠自w的技术实力来开拓市场,研发产品。在公司的发展中Q一定要U篏w的核心技术,U篏一些重要的技术成果,同时也要注重知识理Q这些知识会在公司的不断发展中Ş成公司的核心竞争力,׃会出现由于某一两个人的d而公司受到重创?/span>
创业不是玩家Ӟ创业是实实在在的东西Q创业是要你能按照规则生存下去,可能因ؓ冲动而创业,但创业后不能老冲动,冲动一下,可能你要考虑一些东ѝ?/span>
“行路难Q行路难Q多歧\Q今安在Q长风破会有时Q直挂云帆济沧v”,李白的这句诗用来形容创业之\再脓切不q,在创业之初肯定会遇到很多困难Q但是只要团队团l一_勇于开拓,׃定会有成功的一天?/span>
我们现在q处于创业初期,但是我觉得不只是创业本n使我L匪浅Q同时也让我有了一般大学生所没有的h生体验?/span>
This is an introduction to writing CGI programs in the C language. The reader is assumed to know the basics of C as well how to write simple forms in HTML and to be able to install CGI scripts on a Web server. The principles are illustrated with very simple examples.
METHOD="POST"
As my document How to write HTML forms briefly explains, you need a server side-script in order to use HTML forms reliably. Typically there are simple server-side scripts available for simple, common ways of processing form submissions, such as sending the data in text format by E-mail to a specified address.
But for more advanced processing, such as collecting data into a file or database, or retrieving information and sending it back, or doing some calculations with the submitted data, you will probably need to write a server-side script of your own.
CGI is simply an interface between HTML forms and server-side scripts. It is not the only possibility--see the excellent tutorial How the web works: HTTP and CGI explained by Lars Marius Garshol for both an introduction to the concepts of CGI and notes on other possibilities. But CGI is widely used and useable.
If someone suggests using JavaScript as an alternative to CGI, ask him to read my JavaScript and HTML: possibilities and caveats. Briefly, JavaScript is inherently unreliable at least if not "backed up" with server-side scripting.
The above-mentioned How the web works: HTTP and CGI explained is a great tutorial. There are some shorter introductions like Introduction to the Common Gateway Interface (CGI) in the Virtualville Library. The following introduction of mine is just another attempt to present the basics; please consult other sources if you get confused or need more information.
Let us consider the following simple HTML form:
<FORM ACTION="http://www.cs.tut.fi/cgi-bin/run/~jkorpela/mult.cgi">
<P>Please specify the multiplicands:
<INPUT NAME="m" SIZE="5">
<INPUT NAME="n" SIZE="5"><BR>
<INPUT TYPE="SUBMIT" VALUE="Multiply!">
</FORM>
It will look like the following on your current browser:
You can try it if you like. Just in case the server used isn't running and accessible when you try it, here's what you would get as the result:
Multiplication results
The product of 4 and 9 is 36.
What we discuss here is how it works.
Assume that you type 4 into one input field and
9 into another and then invoke submission (typically,
by clicking on a submit button), your browser will
send, by HTTP, a request to the server at
www.cs.tut.fi
. The browser pick up this server name
from the value of ACTION
attribute where it
occurs as the host name part of a URL.
(Quite often the ACTION
attribute refers, often using
a relative URL, to a script on the same server as the document
resides on, but this is not necessary, as this example shows.)
When sending the request, the browser provides additional information,
specifying a relative URL, in this case/cgi-bin/run/~jkorpela/mult.cgi?m=4&n=9
This was constructed from that part of the ACTION
value
which follows the host name, by appending a question mark
?
and the form data in
a specifically encoded format.
The server to which the request was sent
(in this case, www.cs.tut.fi
)
will then process
it according to its own rules. Typically, the server's configuration
defines how the relative URLs are mapped to file names and which
directories/folders are interpreted as containing CGI scripts.
As you may guess, the part cgi-bin/
in the URL causes
such interpretation in this case. This means that instead of just
picking up and
sending back (to the browser which sent the request) an HTML document
or some other file, the server invokes a script or a program
specified in the URL (mult.cgi
in this case) and passes
some data to it (the data m=4&n=9
in this case).
It depends on the server how this really happens.
In this particular case, the server actually runs the (executable)
program in the file mult.cgi
in the subdirectory
cgi-bin
of user
jkorpela
's home directory. It could be something
quite different, depending on server configuration.
The often-mysticized abbreviation CGI, for Common Gateway Interface, refers just to a convention on how the invocation and parameter passing takes place in detail. Invocation means different things in different cases. For a Perl script, the server would invoke a Perl interpreter and make it execute the script in an interpretive manner. For an executable program, which has typically been produced by a compiler and a loader from a source program in a language like C, it would just be started as a separate process. Although the word script typically suggests that the code is interpreted, the term CGI script refers both to such scripts and to executable programs. See answer to question Is it a script or a program? in CGI Programming FAQ by Nick Kew.
You need to compile and load your C program on the server (or, in principle, on a system with the same architecture, so that binaries produced for it are executable on the server too).
And you need to put the executable into
a suitable directory and name it according to server-specific conventions
For example, if the server runs some flavor of Unix and has the
Gnu C compiler available, you would typically use a compilation
command like gcc -o mult.cgi mult.c
and
then move (mv
) mult.c
to a directory with
a name like cgi-bin
. But you really need to check local
instructions for such issues.
The filename extension .cgi
has no fixed meaning in general. But there can be server-dependent
(and operating system dependent) rules for naming executable files.
Typical extensions for executables are .cgi
and .exe
.
For forms which use METHOD="GET"
(as our
simple example above uses, since
this is the default),
CGI specifications say that the data is passed to
the script or program in an environment variable called
QUERY_STRING
.
It depends on the scripting or programming
language used how a program can access the value of an environment
variable. In the C language, you would use the
library function getenv
(defined in the
standard library stdlib
) to access the value as
a string. You might then use various techniques to pick up data
from the string, convert parts of it to numeric values, etc.
The output from the script or program to "primary output
stream" (such as stdin
in the C language) is handled
in a special way. Effectively, it is directed so that it gets sent
back to the browser. Thus, by writing a C program that it writes
an HTML document onto its standard output, you will make that document
appear on user's screen as a response to the form submission.
In this case, the source program in C is the following:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *data;
long m,n;
printf("%s%c%c\n",
"Content-Type:text/html;charset=iso-8859-1",13,10);
printf("<TITLE>Multiplication results</TITLE>\n");
printf("<H3>Multiplication results</H3>\n");
data = getenv("QUERY_STRING");
if(data == NULL)
printf("<P>Error! Error in passing data from form to script.");
else if(sscanf(data,"m=%ld&n=%ld",&m,&n)!=2)
printf("<P>Error! Invalid data. Data must be numeric.");
else
printf("<P>The product of %ld and %ld is %ld.",m,n,m*n);
return 0;
}
As a disciplined programmer, you have probably noticed that the program makes no check against integer overflow, so it will return bogus results for very large operands. In real life, such checks would be needed, but such considerations would take us too far from our topic.
Note: The first printf
function call prints out
data which will be sent by the server as an HTTP header.
This is required for several reasons, including the fact that
a CGI script can send any data (such as an image or a plain text file)
to the browser, not just HTML documents.
For HTML documents, you can just use the printf
function
call above as such; however, if your
character encoding is different from ISO 8859-1 (ISO Latin 1),
which is the most common on the Web, you need to replace
iso-8859-1
by the
registered name of the encoding ("charset") you use.
I have compiled this program and saved the executable program
under the name mult.cgi
in my directory for CGI scripts
at www.cs.tut.fi
.
This implies that any
form with
action="http://www.cs.tut.fi/cgi-bin/run/~jkorpela/mult.cgi"
will, when submitted, be processed by that program.
As a consequence, anyone could write a form
of his own with the same ACTION
attribute and pass
whatever data he likes to my program. Therefore, the program
needs to be able to handle any data.
Generally, you need to check the data before starting to process it.
METHOD="POST"
Let us consider next a different processing for form data. Assume that we wish to write a form which takes a line of text as input so that the form data is sent to a CGI script which appends the data to a text file on the server. (That text file could be readable by the author of the form and the script only, or it could be made readable to the world through another script.)
It might seem that the problem is similar to the
example considered above; one would just need
a different form and a different script (program).
But in fact, there is a difference. The example above can be regarded
as a "pure query" which does not change the "state of the world",
and in particular it is "idempotent", i.e. the same form data could
be submitted as many times as you like without causing any problems
(except minor waste of resources). But our current task needs
to cause such changes--a change in the content of a file which is
intended to be more or less permanent. Therefore, one should use
METHOD="POST"
. This is explained in more detail in
the document
Methods GET
and POST
in HTML forms - what's the difference?
Here we will take it for granted that
METHOD="POST"
needs to be used and consider the
technical consequences.
For forms which use METHOD="POST"
,
CGI specifications say that the data is passed to
the script or program
in the standard input stream (stdin
), and the
length (in bytes, i.e. characters) of the data is passed
in an environment variable called
CONTENT_LENGTH
.
Reading from standard input sounds probably simpler than
reading from an environment variable, but there are complications.
The server is not required to pass the data so that
when the CGI script tries to read more data than there is, it would
get an end of file indication! That is, if you read e.g. using
the getchar
function in a C program, it is undefined
what happens after reading all the data characters; it is not guaranteed
that the function will return EOF
.
When reading the input, the program must not try to read more
than CONTENT_LENGTH
characters.
A relatively simple
C program
for accepting input via CGI and
METHOD="POST"
is the following:
#include <stdio.h>
#include <stdlib.h>
#define MAXLEN 80
#define EXTRA 5
/* 4 for field name "data", 1 for "=" */
#define MAXINPUT MAXLEN+EXTRA+2
/* 1 for added line break, 1 for trailing NUL */
#define DATAFILE "../data/data.txt"
void unencode(char *src, char *last, char *dest)
{
for(; src != last; src++, dest++)
if(*src == '+')
*dest = ' ';
else if(*src == '%') {
int code;
if(sscanf(src+1, "%2x", &code) != 1) code = '?';
*dest = code;
src +=2; }
else
*dest = *src;
*dest = '\n';
*++dest = '\0';
}
int main(void)
{
char *lenstr;
char input[MAXINPUT], data[MAXINPUT];
long len;
printf("%s%c%c\n",
"Content-Type:text/html;charset=iso-8859-1",13,10);
printf("<TITLE>Response</TITLE>\n");
lenstr = getenv("CONTENT_LENGTH");
if(lenstr == NULL || sscanf(lenstr,"%ld",&len)!=1 || len > MAXLEN)
printf("<P>Error in invocation - wrong FORM probably.");
else {
FILE *f;
fgets(input, len+1, stdin);
unencode(input+EXTRA, input+len, data);
f = fopen(DATAFILE, "a");
if(f == NULL)
printf("<P>Sorry, cannot store your data.");
else
fputs(data, f);
fclose(f);
printf("<P>Thank you! The following contribution of yours has \
been stored:<BR>%s",data);
}
return 0;
}
Essentially, the program retrieves the
information about the number of characters in the input
from value of the
CONTENT_LENGTH
environment variable.
Then it unencodes (decodes) the data, since the data arrives in
a specifically encoded format.
The program has been written for a form where the text input field
has the name data
(actually, just the length of the name
matters here). For example, if the user types
Hello there!
then the data will be passed to the program encoded as
data=Hello+there%21
(with space encoded as +
and exclamation mark encoded
as %21
). The unencode
routine in the program
converts this back to the original format. After that,
the data is appended to a file (with a fixed file name),
as well as echoed back to the user.
Having compiled the program I have saved it as collect.cgi
into the directory for CGI scripts. Now a form like the following
can be used for data submissions:
<FORM ACTION="http://www.cs.tut.fi/cgi-bin/run/~jkorpela/collect.cgi"
METHOD="POST">
<P>Please type your input (80 chars max.):<BR>
<INPUT NAME="data" SIZE="60" MAXLENGTH="80"><BR>
<INPUT TYPE="SUBMIT" VALUE="Send">
</FORM>
Finally, we can write a simple program for viewing the data; it only needs to copy the content of a given text file onto standard output:
#include <stdio.h>
#include <stdlib.h>
#define DATAFILE "../data/data.txt"
int main(void)
{
FILE *f = fopen(DATAFILE,"r");
int ch;
if(f == NULL) {
printf("%s%c%c\n",
"Content-Type:text/html;charset=iso-8859-1",13,10);
printf("<TITLE>Failure</TITLE>\n");
printf("<P><EM>Unable to open data file, sorry!</EM>"); }
else {
printf("%s%c%c\n",
"Content-Type:text/plain;charset=iso-8859-1",13,10);
while((ch=getc(f)) != EOF)
putchar(ch);
fclose(f); }
return 0;
}
Notice that this program prints (when succesful) the data
as plain text, preceded by a header which says this, i.e.
has text/plain
instead of text/html
.
A form which invokes that program can be very simple, since no input data is needed:
<FORM ACTION="http://www.cs.tut.fi/cgi-bin/run/~jkorpela/viewdata.cgi">
<P><INPUT TYPE="SUBMIT" VALUE="View">
</FORM>
Finally, here's what the two forms look like. You can now test them:
Please notice that anything you submit here will become visible to the world:
The content of the text file to which the submissions are stored will be displayed as plain text.
You may now wish to read The CGI specification which tells you all the basic details about CGI. The next step is probably to see what the CGI Programming FAQ contains.
There is a lot of material, including introductions and tutorials, in the CGI Resource Index. Notice in particular the section Programs and Scripts: C and C++: Libraries and Classes which contains libraries which can make it easier to process form data. It can be instructive to parse simple data format by using code of your own, as was done in the simple examples above, but in practical application a library routine might be better.
环境 |
q_Qp520,p550,p570 |
问题 |
p5服务器未接HMC, ׃某种原因pȝ无法d了,需要重启服务器。此时按控制面板上的甉|开兛_不v作用Q该怎么办? |
解答 |
使用控制面板上的功能8 Q可以服务器立卛_机?BR>具体操作步骤Q?/P> a. 使用控制面板?<?gt; ?<?gt; 按钮选择功能2 |