>As he walked by the sea of Galilee, he saw two brothers, Simon, who is called Peter, and Andrew his brother, casting a net into the sea--for they were fishermen. And he said to them,"Follow me, and I will make you fish for people." Immediately they left their nets and followed him.(MATTHEW 5:18-20) #åæHello æå¼ä½ åpython代ç ç¨çç¼è¾å¨ï¼ä¸è¦é®ä¸ºä»ä¹ï¼æä¸é¢ç代ç ä¸ä¸ªåä¸å·®å°å½å ¥è¿å»ï¼å¹¶å½åä¿å为hello.py(ç®å½èªå·±ä»»æå®)ã #!/usr/bin/env python #coding:utf-8 import tornado.httpserver import tornado.ioloop import tornado.options import tornado.web from tornado.options import define, options define("port", default=8000, help="run on the given port", type=int) class IndexHandler(tornado.web.RequestHandler): def get(self): greeting = self.get_argument('greeting', 'Hello') self.write(greeting + ', welcome you to read: www.itdiffer.com') if __name__ == "__main__": tornado.options.parse_command_line() app = tornado.web.Application(handlers=[(r"/", IndexHandler)]) http_server = tornado.httpserver.HTTPServer(app) http_server.listen(options.port) tornado.ioloop.IOLoop.instance().start() è¿å ¥å°ä¿åhello.pyæä»¶çç®å½ï¼æ§è¡ï¼ $ python hello.py ç¨pythonè¿è¡è¿ä¸ªæä»¶ï¼å ¶å®å°±å·²ç»åå¸äºä¸ä¸ªç½ç«ï¼åªä¸è¿è¿ä¸ªç½ç«å¤ªç®åäºã æ¥ä¸æ¥ï¼æå¼æµè§å¨ï¼å¨æµè§å¨ä¸è¾å ¥ï¼http://localhost:8000ï¼å¾å°å¦ä¸çé¢ï¼  æå¨ubuntuçshellä¸è¿å¯ä»¥ç¨ä¸é¢æ¹å¼è¿è¡ï¼ $ curl http://localhost:8000/ Hello, welcome you to read: www.itdiffer.com $ curl http://localhost:8000/?greeting=Qiwsir Qiwsir, welcome you to read: www.itdiffer.com æ¤æä½ï¼è¯»è å¯ä»¥æ ¹æ®èªå·±ç³»ç»èå®ã æåä½ ï¼è¿åºäºå³å®æ§ä¸æ¥ï¼å·²ç»å¯ä»¥ç¨Tornadoåå¸ç½ç«äºãå¨è¿é似乿²¡æåä»ä¹é¨ç½²ï¼åªæ¯å®è£ äºTornadoãæ¯çï¼ä¸éè¦å¤åä»ä¹ï¼å 为Tornadoå°±æ¯ä¸ä¸ªå¾å¥½çserverï¼ä¹æ¯ä¸ä¸ªå¼åæ¡æ¶ã ä¸é¢ä»¥è¿ä¸ªé常ç®åçç½ç«ä¸ºä¾ï¼å¯¹ç¨tornadoåçç½ç«çåºæ¬ç»æè¿è¡è§£éã ##WEBæå¡å¨å·¥ä½æµç¨ ä»»ä½ä¸ä¸ªç½ç«é½ç¦»ä¸å¼Webæå¡å¨ï¼è¿éæè¯´ç䏿¯æé£ä¸ªæ´è®¡ç®æºä¸æ ·ç硬件设å¤ï¼æ¯æéé¢å®è£ çè½¯ä»¶ï¼ææ¶å忬¡æ¥è§¦ççå®å®¹æææ··ãå°±è¿ä¼å¤§ç[ç»´åºç¾ç§é½è¿ä¹è¯´](http://zh.wikipedia.org/wiki/%E6%9C%8D%E5%8A%A1%E5%99%A8)ï¼ >ææ¶ï¼è¿ä¸¤ç§å®ä¹ä¼å¼èµ·æ··æ·ï¼å¦Webæå¡å¨ãå®å¯è½æ¯æç¨äºç½ç«çè®¡ç®æºï¼ä¹å¯è½æ¯æåApacheè¿æ ·ç软件ï¼è¿è¡å¨è¿æ ·çè®¡ç®æºä¸ä»¥ç®¡çç½é¡µç»ä»¶åååºç½é¡µæµè§å¨ç请æ±ã å¨å ·ä½çè¯å¢ä¸ï¼çå®è¦æ³¨æåæï¼å°åºæçæ¯ä»ä¹ã å ³äºWebæå¡å¨æ¯è¾å¥½çè§£éï¼æ¨èççç¾åº¦ç¾ç§çå å®¹ï¼æè¿éå°±ä¸å¤å¶ç²è´´äºï¼å ·ä½å¯ä»¥ç¹å»è¿æ¥æ¥é ï¼[WEBæå¡å¨](http://baike.baidu.com/view/460250.htm) å¨WEBä¸ï¼ç¨çæå¤çå°±æ¯è¾å ¥ç½åï¼è®¿é®æä¸ªç½ç«ãå ¨ä¸çé£ä¹å¤ç½ç«ç½é¡µï¼å¦æå»è®¿é®ï¼æä¹è½å¤åå°å½¼æ¤äºéäºèå¢ã为äºåè°å½¼æ¤ï¼å°±å¶å®äºå¾å¤éç¨çåè®®ï¼å ¶ä¸httpåè®®ï¼å°±æ¯ç½ç»åè®®ä¸çä¸ç§ãå ³äºè¿ä¸ªåè®®çä»ç»ï¼ç½ä¸éå¤å°±è½æ¾å°ï¼è¯·èªå·±google. ç½ä¸å·æ¥ç[ä¸å¼ å¾](http://kenby.iteye.com/blog/1159621)ï¼ä»åªéå·æ¥çï¼æé½åè¯ä½ äºï¼å¤å®å¨åãååãï¼ï¼æ¾ç¤ºå¨ä¸é¢ï¼ç®è¦è¯´æwebæå¡å¨çå·¥ä½è¿ç¨  å·ä¸ªå½»åºï¼æåæä¸ç说æä¹è´´ä¸ï¼ 1. å建listen socket, 卿å®ççå¬ç«¯å£, çå¾ å®¢æ·ç«¯è¯·æ±çå°æ¥ 2. listen socketæ¥å客æ·ç«¯ç请æ±, å¾å°client socket, æ¥ä¸æ¥éè¿client socketä¸å®¢æ·ç«¯éä¿¡ 3. å¤ç客æ·ç«¯ç请æ±, é¦å ä»client socket读åhttp请æ±çå议头, 妿æ¯poståè®®, è¿å¯è½è¦è¯»å客æ·ç«¯ä¸ä¼ çæ°æ®, ç¶åå¤ç请æ±, åå¤å¥½å®¢æ·ç«¯éè¦çæ°æ®, éè¿client socketåç»å®¢æ·ç«¯ ##å¼å ¥æ¨¡å import tornado.httpserver import tornado.ioloop import tornado.options import tornado.web è¿åä¸ªé½æ¯Tornadoçæ¨¡åï¼å¨æ¬ä¾ä¸é½æ¯å¿ é¡»çãå®ä»¬å个å¨ä¸è¬çç½ç«å¼åä¸ï¼é½è¦ç¨å°ï¼åºæ¬ä½ç¨å嫿¯ï¼ - tornado.httpserverï¼è¿ä¸ªæ¨¡åå°±æ¯ç¨æ¥è§£å³webæå¡å¨çhttpåè®®é®é¢ï¼å®æä¾äºä¸å°å±æ§æ¹æ³ï¼å®ç°å®¢æ·ç«¯åæå¡å¨ç«¯çäºéãTornadoçéé»å¡ãå线ç¨çç¹ç¹å¨è¿ä¸ªæ¨¡åä¸ä½ç°ã - tornado.ioloopï¼è¿ä¸ªä¹é常éè¦ï¼è½å¤å®ç°éé»å¡socket循ç¯ï¼ä¸è½äºé䏿¬¡å°±ç»æåã - tornado.optionsï¼è¿æ¯å½ä»¤è¡è§£ææ¨¡åï¼ä¹å¸¸ç¨å°ã - tornado.webï¼è¿æ¯å¿ ä¸å¯å°ç模åï¼å®æä¾äºä¸ä¸ªç®åçWebæ¡æ¶ä¸å¼æ¥åè½ï¼ä»èä½¿å ¶æ©å±å°å¤§éæå¼çè¿æ¥ï¼ä½¿å ¶æä¸ºçæ³çé¿è½®è¯¢ã 读è çå°è¿éå¯è½æç¹è«åå ¶å¦ï¼å¯¹ä¸äºå±äºä¸çè§£ãæ²¡å ³ç³»ï¼ä½ å¯ä»¥å ä¸ç¨ç®¡å®ï¼å¦ææ¿æç®¡ï¼å°±æä¸çè§£å±äºæ¾å°googleç«é¢æ¥æ¥çãä¸å®è¦ç¡¬ç头ç®ä¸åä¸å¥å°è¯»ä¸å»ï¼éçå¦ä¹ åå®è·µçæ·±å ¥ï¼ç°å¨ä¸çè§£ç以åå°±ä¼éæ¸é¢æçè§£çã è¿æä¸ä¸ªæ¨¡åå¼å ¥ï¼æ¯ç¨from...import宿ç from tornado.options import define, options define("port", default=8000, help="run on the given port", type=int) è¿ä¸¤å¥å°±æ¾ç¤ºäºæè°âå½ä»¤è¡è§£ææ¨¡åâçç¨éäºãå¨è¿ééè¿`tornado.options.define()`å®ä¹äºè®¿é®æ¬æå¡å¨ç端å£ï¼å°±æ¯å½å¨æµè§å¨å°åæ ä¸è¾å ¥`http:localhost:8000`çæ¶åï¼æè½è®¿é®æ¬ç½ç«ï¼å 为httpåè®®é»è®¤çç«¯å£æ¯80ï¼ä¸ºäºåºåï¼æå¨è¿é设置为8000,为ä»ä¹è¦åºåå¢ï¼å 为æçè®¡ç®æºæè®¸ä½ ç乿¯ï¼å·²ç»é¨ç½²äºå«ï¼æè®¸æ¯NginxãApacheï¼æå¡å¨äºï¼å®çç«¯å£æ¯80,æä»¥è¦åºåå¼ï¼ä¹å¯è½æ¯æ æä¸ç¨80端å£ï¼ï¼å¹¶ä¸ï¼å颿们è¿ä¼å°tornadoåNginxèåèµ·æ¥å·¥ä½ï¼è¿æ ·ä¸¤ä¸ªæå¡å¨å¨åä¸å°è®¡ç®æºä¸ï¼å°±è¦åå¼å½ã ##å®ä¹è¯·æ±-å¤çç¨åºç±» class IndexHandler(tornado.web.RequestHandler): def get(self): greeting = self.get_argument('greeting', 'Hello') self.write(greeting + ', welcome you to read: www.itdiffer.com') æè°â请æ±å¤çâç¨åºç±»ï¼å°±æ¯è¦å®ä¹ä¸ä¸ªç±»ï¼ä¸é¨åºä»å®¢æ·ç«¯ï¼å°±æ¯ä½ æå¼çé£ä¸ªæµè§å¨çé¢ï¼åæå¡å¨æåºç请æ±ï¼è¿ä¸ªè¯·æ±ä¹è®¸æ¯è¦è¯»åæä¸ªç½é¡µï¼ä¹è®¸æ¯è¦å°æäºä¿¡æ¯åå°æå¡å¨ä¸ï¼ï¼æå¡å¨è¦æç¸åºçç¨åºæ¥æ¥æ¶å¹¶å¤çè¿ä¸ªè¯·æ±ï¼å¹¶ä¸å馿äºä¿¡æ¯ï¼æè æ¯é对请æ±å馿è¦çä¿¡æ¯ï¼æè è¿åå ¶å®çé误信æ¯çï¼ã äºæ¯ï¼å°±å®ä¹äºä¸ä¸ªç±»ï¼å忝IndexHandlerï¼å½ç¶ï¼ååå¯ä»¥é便åäºï¼ä½æ¯ï¼æç §ä¹ æ¯ï¼ç±»çååä¸çåè¯é¦åæ¯é½æ¯å¤§åçï¼å¹¶ä¸å¦æè¿ä¸ªç±»æ¯è¯·æ±å¤çç¨åºç±»ï¼é£ä¹å°±æå¥½ç¨Handlerç»å°¾ï¼è¿æ ·å¨åç§°ä¸å¾æç¡®ï¼æ¯å¹²ä»ä¹çã ç±»IndexHandlerç»§æ¿`tornado.web.RequestHandler`,å ¶ä¸åå®ä¹`get()`å`post()`两个å¨webä¸åºç¨æå¤çæ¹æ³çå 容ï¼å ³äºè¿ä¸¤ä¸ªæ¹æ³ç详ç»è§£éï¼å¯ä»¥åèï¼[HTTP GET POSTçæ¬è´¨åºå«è¯¦è§£](https://github.com/qiwsir/ITArticles/blob/master/Tornado/DifferenceHttpGetPost.md)ï¼ä½è å¨è¿ç¯æç« ä¸ï¼éè¿°äºä¸¤ä¸ªæ¹æ³çæ¬è´¨ï¼ã 卿¬ä¾ä¸ï¼åªå®ä¹äºä¸ä¸ª`get()`æ¹æ³ã ç¨`greeting = self.get_argument('greeting', 'Hello')`çæ¹å¼å¯ä»¥å¾å°urlä¸ä¼ éçåæ°ï¼æ¯å¦ $ curl http://localhost:8000/?greeting=Qiwsir Qiwsir, welcome you to read: www.itdiffer.com å°±å¾å°äºå¨urlä¸ä¸ºgreeting设å®çå¼Qiwsirã妿url䏿²¡ææä¾å¼ï¼å°±æ¯Hello. 宿¹ææ¡£å¯¹è¿ä¸ªæ¹æ³çæè¿°å¦ä¸ï¼ >RequestHandler.get_argument(name, default=, []strip=True) >Returns the value of the argument with the given name. >If default is not provided, the argument is considered to be required, and we raise a MissingArgumentError if it is missing. >If the argument appears in the url more than once, we return the last value. >The returned value is always unicode. æ¥ä¸æ¥çé£å¥`self.write(greeting + ',weblcome you to read: www.itdiffer.com)'`ä¸ï¼`write()`æ¹æ³ä¸»è¦åè½æ¯å客æ·ç«¯åé¦ä¿¡æ¯ã乿µè§ä¸ä¸å®æ¹ææ¡£ä¿¡æ¯ï¼å¯¹ä»¥åæ£ç¡®çè§£ä½¿ç¨æå¸®å©ï¼ >RequestHandler.write(chunk)[source] >Writes the given chunk to the output buffer. >To write the output to the network, use the flush() method below. >If the given chunk is a dictionary, we write it as JSON and set the Content-Type of the response to be application/json. (if you want to send JSON as a different Content-Type, call set_header after calling write()). ##main()æ¹æ³ `if __name__ == "__main__"`,è¿ä¸ªæ¹æ³è·ä»¥å¾æ§è¡pythonç¨åºæ¯ä¸æ ·çã `tornado.options.parse_command_line()`,è¿æ¯å¨æ§è¡tornadoçè§£æå½ä»¤è¡ãå¨tornadoçç¨åºä¸ï¼åªè¦import模åä¹åï¼å°±ä¼å¨è¿è¡çæ¶åèªå¨å è½½ï¼ä¸éè¦äºè§£ç»èï¼ä½æ¯ï¼å¨mainï¼ï¼æ¹æ³ä¸å¦ææå½ä»¤è¡è§£æï¼å¿ é¡»è¦æåå°æ¨¡åå¼å ¥ã ##Applicationç±» ä¸é¢è¿å¥æ¯éç¹ï¼ app = tornado.web.Application(handlers=[(r"/", IndexHandler)]) å°tornado.web.Applicationç±»å®ä¾åãè¿ä¸ªå®ä¾åï¼æ¬è´¨ä¸æ¯å»ºç«äºæ´ä¸ªç½ç«ç¨åºç请æ±å¤çéåï¼ç¶åå®å¯ä»¥è¢«HTTPServeråä¸ºåæ°è°ç¨ï¼å®ç°httpåè®®æå¡å¨è®¿é®ãApplicationç±»ç`__init__`æ¹æ³åæ°å½¢å¼ï¼ def __init__(self, handlers=None, default_host="", transforms=None,**settings): pass å¨ä¸è¬æ åµä¸ï¼handlersæ¯ä¸è½ä¸ºç©ºçï¼å 为Applicationç±»éè¿è¿ä¸ªåæ°çå¼å¤çæå¾å°ç请æ±ãä¾å¦å¨æ¬ä¾ä¸ï¼`handlers=[(r"/", IndexHandler)]`ï¼å°±æå³ç妿éè¿æµè§å¨çå°åæ è¾å ¥æ ¹è·¯å¾ï¼`http://localhost:8000`å°±æ¯æ ¹è·¯å¾ï¼å¦ææ¯`http://localhost:8000/qiwsir`ï¼å°±ä¸å±äºæ ¹ï¼èæ¯ä¸ä¸ªåè·¯å¾æç®å½äºï¼ï¼å¯¹åºçå°±æ¯è®©åå为IndexHandlerç±»å¤çè¿ä¸ªè¯·æ±ã éè¿handlersä¼ å ¥çæ°å¼æ ¼å¼ï¼ä¸å®è¦æ³¨æï¼å¨åé¢åå¤æç»æçç½ç«æ¯ï¼è¿éå°±æ¾å¾éè¦äºã宿¯ä¸ä¸ªlistï¼listéé¢çå ç´ æ¯tupleï¼tupleçç»æå æ¬ä¸¤é¨åï¼ä¸é¨åæ¯è¯·æ±è·¯å¾ï¼å¦å¤ä¸é¨åæ¯å¤çç¨åºçç±»åç§°ãæ³¨æè¯·æ±è·¯å¾å¯ä»¥ç¨æ£å表达å¼ä¹¦å(å ³äºæ£å表达å¼ï¼åé¢ä¼è¿è¡ç®è¦ä»ç»)ã举ä¾è¯´æï¼ handlers = [ (r"/", IndexHandlers), #æ¥èªæ ¹è·¯å¾ç请æ±ç¨IndesHandlerså¤ç (r"/qiwsir/(.*)", QiwsirHandlers), #æ¥èª/qiwsir/以åå ¶ä¸ä»»ä½è¯·æ±ï¼æ£å表达å¼è¡¨ç¤ºä»»ä½å符ï¼é½ç±QiwsirHandlerså¤ç ] **注æ** å¨è¿éæä½¿ç¨äº`r"/"`çæ ·å¼ï¼æå³çå°±ä¸éè¦ä½¿ç¨è½¬ä¹ç¬¦ï¼råé¢çé½è¡¨ç¤ºè¯¥ç¬¦å·æ¬æ¥çå«ä¹ãä¾å¦ï¼\nï¼å¦æå纯è¿ä¹æ¥ä½¿ç¨ï¼å°±ä»¥ä¸ºçæ¢è¡ï¼å 为符å·â\âå ·æè½¬ä¹åè½ï¼å ³äºè½¬ä¹è¯¦ç»é 读[ãå符串(1)ã](./106.md)ï¼ï¼å½åæ`r"\n"`ç形弿¯ï¼å°±ä¸å表示æ¢è¡äºï¼èæ¯ä¸¤ä¸ªå符ï¼\ånï¼ä¸ä¼è½¬æãä¸è¬æ åµä¸ï¼ç±äºæ£å表达å¼å \ 伿å²çªï¼å æ¤ï¼å½ä¸ä¸ªå符串使ç¨äºæ£å表达å¼åï¼æå¥½å¨åé¢å ä¸'r'ã å ³äºApplicationç±»çä»ç»ï¼å䏿®µè½ï¼ä½æ¯å¹¶æªå®å ¨è®²è¿°äºï¼å ä¸ºè¿æå«çåæ°è®¾ç½®æ²¡æè®²ï¼è¯·ç»§ç»å ³æ³¨åç»å 容ã ##HTTPServerç±» å®ä¾åä¹åï¼Application对象ï¼ç¨appå为æ ç¾çï¼å°±å¯ä»¥è¢«å¦å¤ä¸ä¸ªç±»HTTPServerå¼ç¨ï¼å½¢å¼ä¸ºï¼ http_server = tornado.httpserver.HTTPServer(app) HTTPServeræ¯tornado.httpserveréé¢å®ä¹çç±»ãHTTPServeræ¯ä¸ä¸ªå线ç¨éé»å¡HTTPæå¡å¨ï¼æ§è¡HTTPServerä¸è¬è¦åè°Application对象ï¼å¹¶æä¾åéååºçæ¥å£,ä¹å°±æ¯ä¸é¢çå 容æ¯è·éä¸é¢è¯å¥çï¼options.portçå¼å¨IndexHandlerç±»åé¢éè¿from...import..设置çï¼ã http_server.listen(options.port) è¿ç§æ¹æ³ï¼å°±å»ºç«äºåè¿ç¨çhttpæå¡ã 请çå®ç¢è®°ï¼å¦æå¨ä»¥åç¼ç ä¸ï¼éå°éè¦å¤è¿ç¨ï¼è¯·åè宿¹ææ¡£è¯´æï¼http://tornado.readthedocs.org/en/latest/httpserver.html#http-server ##IOLoopç±» å©ä¸æåä¸å¥äºï¼ tornado.ioloop.IOLoop.instance().start() è¿å¥è¯ï¼æ»æ¯å¨`__main()__`çæåä¸å¥ã表示å¯ä»¥æ¥æ¶æ¥èªHTTPç请æ±äºã 以䏿ä¸ä¸ªç®åçhello.pyåæãæ³å¿ 读è 对Tornadoç¼åç½ç«çåºæ¬æ¦å¿µå·²ç»æäºã 妿ä¸å¤´é¾æ°´ï¼ä¹ä¸è¦çæ¥ï¼è¯·å°ä¸é¢çå 容å¤çå éã对æ´ä½ç»ææä¸ä¸ªåºæ¬äºè§£ï¼ä¸è¦ææ³¥äºç»èæè æäºè¯æ±å«ä¹ãç¶åå³ç»§ç»å¦ä¹ ã ------ [æ»ç®å½](./index.md) | [ä¸èï¼ä¸ºåç½ç«èåå¤](./301.md) | [ä¸èï¼ç¨tornadoåç½ç«(1)](./303.md) å¦æä½ è®¤ä¸ºæå¿ è¦æèµæï¼è¯·éè¿æ¯ä»å®ï¼**[email protected]**,ä¸èææ¿ã