当前位置:首页 > 商讯 >

Python学习笔记20:服务器进阶

编辑:北京盛典时光文化传媒有限公司时间:2017-09-08 18:19:07阅读次数:2
Python学习笔记20:服务器进阶 上一篇我们在不依赖框架和CGI的情况下,仅使用socket接口,完成了一个可以处理HTTP请求的Python服务器。
基于此,任何一台装有操作系统(推荐Linux)和Python的计算机都可以作为HTTP服务器使用,来架设你的网站。

我们将在这里不断改写上一篇文章中的程序,并引入更高级的Python包,以写出更成熟的Python服务器。


一 支持POST 我们首先改写原文中的HTTP服务器,从而让该服务器支持更加丰富的HTTP请求。
相对于原程序,这里增添了表格以及对应”POST”方法的操作。如果你已经读过用socket写一个Python服务器,会发现这里只是增加很少的一点内容。
原始程序:

# A messy HTTP server based on TCP socket import socket # Address HOST = '' PORT = 8000 text_content = ''' HTTP/1.x 200 OK Content-Type: text/html

Wow, Python Server

''' f = open('http://www.2cto.com/uploadfile/2014/1021/20141021103452295.jpg','rb') pic_content = ''' HTTP/1.x 200 OK Content-Type: image/jpg ''' pic_content = pic_content + f.read() # Configure socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((HOST, PORT)) # Serve forever while True: s.listen(3) conn, addr = s.accept() request = conn.recv(1024) # 1024 is the receiving buffer size method = request.split(' ')[0] src = request.split(' ')[1] print 'Connected by', addr print 'Request is:', request # if GET method request if method == 'GET': # if ULR is /http://www.2cto.com/uploadfile/2014/1021/20141021103452295.jpg if src == '/http://www.2cto.com/uploadfile/2014/1021/20141021103452295.jpg': content = pic_content else: content = text_content # send message conn.sendall(content) # if POST method request if method == 'POST': form = request.split('rn') idx = form.index('') # Find the empty line entry = form[idx:] # Main content of the request value = entry[-1].split('=')[-1] conn.sendall(text_content + 'n

' + value + '

') ###### # More operations, such as put the form into database # ... ###### # close connection conn.close()

运行上面Python服务器,向上一篇文章那样,使用一个浏览器作为客户端。
我们看到了新增的表格以及提交(submit)按钮。在表格中输入aa并提交表格,我们的Python服务器给出上面的结果。

二 使用SocketServer 我们首先使用SocketServer包来简化我们架设服务器的过程。
在上面使用socket的过程中,我们先设置了socket的类型,然后依次调用bind(),listen(),accept(),并使用while循环来让服务器不断的接受请求。
上面的这些步骤可以通过SocketServer包来简化。

SocketServer: # use TCPServer import SocketServer HOST = '' PORT = 8000 text_content = ''' HTTP/1.x 200 OK Content-Type: text/html

Wow, Python Server

''' f = open('http://www.2cto.com/uploadfile/2014/1021/20141021103452295.jpg','rb') pic_content = ''' HTTP/1.x 200 OK Content-Type: image/jpg ''' pic_content = pic_content + f.read() # This class defines response to each request class MyTCPHandler(SocketServer.BaseRequestHandler): def handle(self): # self.request is the TCP socket connected to the client request = self.request.recv(1024) print 'Connected by',self.client_address[0] print 'Request is', request method = request.split(' ')[0] src = request.split(' ')[1] if method == 'GET': if src == '/http://www.2cto.com/uploadfile/2014/1021/20141021103452295.jpg': content = pic_content else: content = text_content self.request.sendall(content) if method == 'POST': form = request.split('rn') idx = form.index('') # Find the empty line entry = form[idx:] # Main content of the request value = entry[-1].split('=')[-1] self.request.sendall(text_content + 'n

' + value + '

') ###### # More operations, such as put the form into database # ... ###### # Create the server server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler) # Start the server, and work forever server.serve_forever()
我们建立了一个TCPServer对象来创建一个TCP socket服务器,并同时设置IP地址和端口。
然后使用server_forever()方法来让服务器不断工作(就像原始程序中的while循环一样)。
我们传递给TCPServer一个MyTCPHandler类,用对socket作出操作。
注意,MyTCPHandler继承自BaseRequestHandler,我们通过改写handler()方法来个性化我们的操作。
在handler()中,可以通过self.request来引用socket (正如我们在handler()中对socket进行recv()和sendall()操作),
还可以使用self.address来引用socket的客户端地址。
三 SimpleHTTPServer: 使用静态文件来回应请求 在经过了SocketServer的改造之后,我们的handler(),也就是对请求进行处理的部分,依然是乱糟糟的一团。
这对于大型服务器来说可能是个问题。
为什么呢? 对于一个HTTP请求(request)来说,它的起始行包含两个重要信息:请求方法和URL。
之前,我们都用if结构来区分不同的请求方法和URL,并针对不同的情况来进行不同的操作:


请求方法(request method) URL 操作


GET / 发送text_content


GET /text.jpg 发送pic_content


POST / 分析request主体中包含的value(实际上是我们填入表格的内容); 发送text_content和value

根据请求方法和URL的不同,一个大型的HTTP服务器可能需要应付成千上万种不同的请求。
如果针对每个请求都在程序中写出不同的操作的话,需要大量的时间和精力,同时为运营和维护带来很大的困难。
我们需要有更标准化,也更简便的方式来处理这些请求。
在Python中,我们可以使用SimpleHTTPServer包和CGIHTTPServer包来减小以上的负担。
其中,SimpleHTTPServer可以用于处理GET方法和HEAD方法的请求。
它读取request中的URL地址,并在当前目录中找到对应的静态文件,并将文件的内容发送给客户端。
对应于我们的情况,就是将text_content放置在index.html中,而不用读取text.jpg文件。
当一个HTTP请求到来时,其URL指向某个文件,SimpleHTTPServer会读取这个文件,并分析文件类型,自动生成response,回复客户端。
如果URL指向某个文件夹,SimpleHTTPServer会读取该文件夹下的index.html或者index.hml文件。
首先,我们在当前目录下生成如下index.html文件:

企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:咸宁SEO http://xianning.raoyu.net

上一篇:社交媒体营销策略之粉丝养成计 下一篇:最后一页

相关阅读