实例讲解Python中SocketServer模块处理网络请求的用法


Posted in Python onJune 28, 2016

SocketServer创建一个网络服务框架。它定义了类来处理TCP,UDP, UNIX streams 和UNIX datagrams上的同步网络请求。

一、Server Types

有五个不同的服务器类在SocketServer中。

1.BaseServer定义了API, 而且他不是用来实例化和直接使用的。
2.TCPServer用作TCP/IP的socket通讯。
3.UDPServer使用datagram sockets。
4.UnixStreamServer和UnixDatagramServer使用Unix-domain sockets而且智能在unix平台上使用。

二、Server Objects

构建一个服务器, 通过它来监听请求的地址和请求的处理类(not instance)。

1.class SocketServer.BaseServer
这是模块中所有服务器对象的超类,它定义了接口,实现大多数都在子类中完成。

2.BaseServer.fileno

返回一个整数文件描述符来表示哪个服务器正在监听。这个函数最常见的传递给select.select(),允许监控多个相同处理过程的服务。

3.BaseServer.handle_request

处理单一的请求,这个函数会顺序调用接下来的方法。get_request(),verify_request和proccess_request。
用户提供handle()方法抛出一个异常,那么handle_error()方法会被调用。
self.timeout的时间内没有收到请求,handle_timeout()和handle_request()将返回。

4.BaseServer.serve_forever

BaseServer.serve_forever(poll_interval=0.5),处理请求一直到明确的shutdown()请求。轮训每隔poll_interval时间内关闭。忽略self.timeout,如果需要使用定时任务,需要使用其他线程。

5.BaseServer.shutdown

告诉serve_forever()循环停止。

6.BaseServer.RequestHandlerClass

用户请求处理程序类,为每个请求创建这个类的一个实例。

三、Implementing a Server

如果你创建一个服务器,它通常可以重复使用现有的类和简单的提供一个自定义请求处理的类。如果不符合需求,有几种BaseServer方法覆盖一个子类。

1.verify_request(reqeust, client_address): 必须返回一个布尔值,如果返回True,请求将被处理,如果返回False,请求将被拒绝。这个函数可以覆盖来实现访问控制服务。
2.process_request(request, client_address): 调用finish_request来创建一个RequestHandlerClass()的实例,如果需要该函数可以创建一个新的进程或协程来处理请求。
3.finish_request(request, client_address): 创建一个请求处理实例。调用handle()来处理请求。

四、Request Handlers

请求处理程序做的大部分工作接收传入的请求,并决定采取何种行动。处理程序负责实现“协议”上的套接字层(例如,HTTP或xml - rpc)。从传入的请求处理程序读取请求数据通道,流程,和写一个响应。有三个方法可以重写。

1.setup(): 准备请求的请求处理程序, 就是初始化运行在handle之前。
2.handle(): 做真正的请求工作。解析传入的请求,处理数据和返回响应。
3.finish(): 清理任意时间创建的setup()。

五、例子

下面例子展示了tcp, udp和异步

1.TCPServer 例子

import SocketServer


class MyHandler(SocketServer.BaseRequestHandler):
  
  def handle(self):
    self.data = self.request.recv(1024).strip()
    print '{} wrote:'.format(self.client_address[0])
    print self.data
    self.request.sendall(self.data.upper())


if __name__ == '__main__':
  HOST, PORT = 'localhost', 9999
  server = SocketServer.TCPServer((HOST, PORT), MyHandler)
  server.serve_forever()

2.UDPServr 例子

import SocketServer


class MyHandler(SocketServer.BaseRequestHandler):

  def handle(self):
    data = self.request[0].strip()
    socket = self.request[1]
    print '{} wrote:'.format(self.client_address[0])
    print data
    socket.sendto(data.upper(), self.client_address)


if __name__ == '__main__':
  HOST, PORT = 'localhost', 9999
  server = SocketServer.UDPServer((HOST, PORT), MyHandler)
  server.serve_forever()

3.异步例子

可以通过ThreadingMixIn和ForkingMixIn类来构造异步处理程序。

import socket
import threading
import SocketServer


class MyHandler(SocketServer.BaseRequestHandler):

  def handle(self):
    data = self.request.recv(1024)
    curr_thread = threading.current_thread()
    response = '{}: {}'.format(curr_thread.name, data)
    self.request.sendall(response)


class Server(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
  pass


def client(ip, port, message):
  sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  sock.connect((ip, port))
  try:
    sock.sendall(message)
    response = sock.recv(1024)
    print 'Received: {}'.format(response)
  finally:
    sock.close()


if __name__ == '__main__':
  HOST, PORT = 'localhost', 0

  server = Server((HOST, PORT), MyHandler)
  ip, port = server.server_address

  serer_thread = threading.Thread(target=server.serve_forever)
  server_thread.daemon = True
  server_thread.start()
  print 'Server loop running in thread:', server_thread.name

  client(ip, port, 'Hello World 1')
  client(ip, port, 'Hello World 2')
  client(ip, port, 'Hello World 3')

  server.shutdown()
  server.server_close()

4.SocketServer 实现客户端与服务器间非阻塞通信
(1)创建SocketServerTCP服务端

#创建SocketServerTCP服务器: 
import SocketServer 
from SocketServer import StreamRequestHandler as SRH 
from time import ctime 
 
host = 'xxx.xxx.xxx.xxx' 
port = 9999 
addr = (host,port) 
 
class Servers(SRH): 
  def handle(self): 
    print 'got connection from ',self.client_address 
    self.wfile.write('connection %s:%s at %s succeed!' % (host,port,ctime())) 
    while True: 
      data = self.request.recv(1024) 
      if not data:  
        break 
      print data 
      print "RECV from ", self.client_address[0] 
      self.request.send(data) 
print 'server is running....' 
server = SocketServer.ThreadingTCPServer(addr,Servers) 
server.serve_forever()

(2)创建SocketServerTCP客户端

from socket import * 
 
host = 'xxx.xxx.xxx.xxx' 
port = 9999 
bufsize = 1024 
addr = (host,port) 
client = socket(AF_INET,SOCK_STREAM) 
client.connect(addr) 
while True: 
  data = raw_input() 
  if not data or data=='exit': 
    break 
  client.send('%s\r\n' % data) 
  data = client.recv(bufsize) 
  if not data: 
    break 
  print data.strip() 
client.close()
Python 相关文章推荐
python教程之用py2exe将PY文件转成EXE文件
Jun 12 Python
Python3中的2to3转换工具使用示例
Jun 12 Python
pycharm中连接mysql数据库的步骤详解
May 02 Python
python async with和async for的使用
Jun 20 Python
Python解决pip install时出现的Could not fetch URL问题
Aug 01 Python
python 计算积分图和haar特征的实例代码
Nov 20 Python
python程序文件扩展名知识点详解
Feb 27 Python
对python中各个response的使用说明
Mar 28 Python
浅谈django框架集成swagger以及自定义参数问题
Jul 07 Python
高考考python编程是真的吗
Jul 20 Python
python中pow函数用法及功能说明
Dec 04 Python
python中的插入排序的简单用法
Jan 19 Python
Python中asyncore异步模块的用法及实现httpclient的实例
Jun 28 #Python
python 字典(dict)按键和值排序
Jun 28 #Python
简单谈谈python的反射机制
Jun 28 #Python
Python实现带百分比的进度条
Jun 28 #Python
Python中的字符串替换操作示例
Jun 27 #Python
Python的string模块中的Template类字符串模板用法
Jun 27 #Python
Python的Flask框架及Nginx实现静态文件访问限制功能
Jun 27 #Python
You might like
PHP5多态性与动态绑定介绍
2015/04/03 PHP
php之可变函数的实例详解
2017/09/13 PHP
ThinkPHP5.1验证码功能实现的示例代码
2020/06/08 PHP
javascript代码编写需要注意的7个小细节小结
2011/09/21 Javascript
JS 实现点击a标签的时候让其背景更换
2013/10/15 Javascript
Javascript脚本实现静态网页加密实例代码
2013/11/05 Javascript
深入剖析JavaScript中的枚举功能
2014/03/06 Javascript
JQuery对表格进行操作的常用技巧总结
2014/04/23 Javascript
5款JavaScript代码压缩工具推荐
2014/07/07 Javascript
jquery中one()方法的用法实例
2015/01/16 Javascript
jQuery实现感应鼠标动画效果自动伸长的输入框实例
2015/02/24 Javascript
JS实现可缩放、拖动、关闭和最小化的浮动窗口完整实例
2015/03/04 Javascript
BootStrap点击下拉菜单项后显示一个新的输入框实现代码
2016/05/16 Javascript
JavaScript 最佳实践:帮你提升代码质量
2016/12/03 Javascript
纯javaScript、jQuery实现个性化图片轮播【推荐】
2017/01/08 Javascript
详解vue.js+UEditor集成 [前后端分离项目]
2017/07/07 Javascript
React.Js添加与删除onScroll事件的方法详解
2017/11/03 Javascript
jackson解析json字符串,首字母大写会自动转为小写的方法
2017/12/22 Javascript
小程序实现列表点赞功能
2018/11/02 Javascript
详解Webstorm 下的Angular2.0开发之路(图文)
2018/12/06 Javascript
Layui数据表格 前后端json数据接收的方法
2019/09/19 Javascript
[00:32]2018DOTA2亚洲邀请赛iG出场
2018/04/03 DOTA
[01:20:38]完美世界DOTA2联赛 GXR vs IO 第一场 11.07
2020/11/09 DOTA
Python中用于计算对数的log()方法
2015/05/15 Python
解决python 文本过滤和清理问题
2019/08/28 Python
Python 静态方法和类方法实例分析
2019/11/21 Python
Pycharm中配置远程Docker运行环境的教程图解
2020/06/11 Python
Canvas高级路径操作之拖拽对象的实现
2019/08/05 HTML / CSS
运行时异常与一般异常有何异同?
2014/01/05 面试题
WebSphere 应用服务器都支持哪些认证
2013/12/26 面试题
Servlet的生命周期
2013/08/25 面试题
不错的求职信范文
2014/07/20 职场文书
宾馆客房管理制度
2015/08/06 职场文书
优秀学生主要事迹怎么写
2015/11/04 职场文书
python使用pygame创建精灵Sprite
2021/04/06 Python
xhunter1.sys可以删除嘛? win11提示xhunter1.sys驱动不兼容解决办法
2022/09/23 数码科技