StreamRequestHandler

   建立一个 SocketServer 所要做的大部分工作是定义一个请求处理( request handler )类。它是 SocktServer 模块里 BaseRequestHandler 类的子类,并且每一个 request handler 对象在客户端连接到服务端时处理着一个客户端的请求。这是在请求处理的 handle 方法里实现的。当然请求处理也可以通过对 setup 和 finish 方法的重载来定义每个请求设置和请求拆下时的代码。

      BaseRequestHandler 子类方法可以接触到下面三个变量:

      request: 一个 socket 对象代表着客户端的请求。在 MirrorServer 例子里 socket.accept 也返回这样一个对象。

  •       client_address:一个包含两个成员(主机名和端口)的数组,服务端输出的任何数据都将通过它们发送。 在MirrorServer 例子中 socket.accept 返回的另一个参数就是 client_address。 
  •       server: 对创建 request handler 对象的 SocketServer 的一个引用。

      继承 StreamRequestHandler 代替继承 BaseRequestHandler ,你可以像文件操作一样对 socket 连接进行读写。 StreamRequestHandler 提供了另外两个变量:

      rfile: 这个文件对应着从 socket 进来的数据。等同于调用 request.makefile(‘rb’) 。

      wfile: 这个文件对应着从 socket 发送的数据。等同于调用 request.makefile(‘wb’)。

      通过用将 MirrorServer 重写为一个 SocketServer 服务端(更确切,是一个 TCPServer ),你可以省略 socket 配置和拆除的大量相关代码,而专心地致力于文本的逆反工作。下面是 MirrorSocketServer.py:

MirrorSocketServer#!/usr/bin/python
import SocketServer

class RequestHandler(SocketServer.StreamRequestHandler):
	"Handles one request to mirror some text"

	def handle(self):
		"""Read from StreamRequestHandler's provided rfile member,
		which contains the input from the client.Mirror the text
		and write it to the wfile member, which contains the output
		to be sent to the client."""
		l = True
		while l:
			l = self.rfile.readline().strip()
			if l:
				self.wfile.write(l[::-1] + '\n')


if __name__ = '__main__':
	import sys
	if len(sys.argv) < 3:
		print 'Usage: %s [hostname] [port number]' % sys.argv[0]
		sys.exit(1)
	hostname = sys.argv[1]
	port = int(sys.argv[2])

	SocketServer.TCPServer((hostname,port), RequestHandler).serve_forever()

      几乎所有 socket 细节的代码都没有。无论什么时候连接到这个服务端, TCPServer 类将传递正确的变量来建立一个新的  RequestHandler ,并调用 handle 方法来处理请求。

      ∵两个服务端在网络上所接收输入和发送的输出都是一样的,∴前面我们所写的 MirrorClient 也可以很好地与这个服务端工作。这个原则也适用于当你为精简代码面改变模块里面函数的实现,但保留了接口的一致。

 

Python的标准库里的服务器模块SocketServer可以很方便的开发简单的服务器程序

 

 

import SocketServer
class MyHandler(SocketServer.StreamRequestHandler):
	def handle():
		addr = self.request.getpeername()
		print 'connection from:", addr
		data = self.rfile.read(1024)
		print 'data:', data
		self.wfile.write('xxx')
server = SocketServer.ThreadingTCPServer((ip, host), MyHandler)
server.serve_forever()
对于UDP而言,StreamRequestHandler还可以用DatagramRequestHandler代替,ThreadingTCPServer可以用TCPServer, UDPServer代替
在 Python标准库里有如下定义:
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
	pass
StreamRequestHandler是BaseRequestHandler的一个子类,我们需要创建一个自己的handler类,继承自StreamRequestHandler,
并重载StreamRequestHandler.handle()方法。
StreamRequestHandler.handle()方法的调用顺序为: 
StreamRequestHandler.setup()->StreamRequestHandler.handle()->StreamRequestHandler.finish(),setup和finish调用啥也不做,可以无视
该类中,self.client_address表示客户端地址,如果是StreamRequestHandler, self.request表示socket,如果是DatagramRequestHandler, 
self.request是(socket, data)的tuple。同时self.rfile, self.wfile可以用来读写
在标准库里,BaseServer通过handle_request来处理请求(serve_forever就是不停调用handle_request)。handle_request()中包含了
get_request, verify_request, process_request, finish_request。其中finish_request会调用StreamRequestHandler的handle方法。
而process_request会继承自ThreadingMixIn或者ForkingMixIn,对每个request新建线程,然后由线程调用finish_request
BaseServer的其他属性和方法请参考Python Library Reference:
BaseServer.socket: listen的socket
BaseServer.shutdown(): stop serve_forever() loop
BaseServer.allow_reuse_address
BaseServer.request_queue_size
BaseServer.handle_error: 如果RequestHandler的handle方法抛出异常,由handle_error处理

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值