实例讲解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 文件和输入输出小结
Oct 09 Python
Python中apply函数的用法实例教程
Jul 31 Python
python3中set(集合)的语法总结分享
Mar 24 Python
python smtplib发送带附件邮件小程序
May 22 Python
Win10系统下安装labelme及json文件批量转化方法
Jul 30 Python
Python3.7 读取 mp3 音频文件生成波形图效果
Nov 05 Python
Python实现自定义读写分离代码实例
Nov 16 Python
python中seaborn包常用图形使用详解
Nov 25 Python
Python实现不规则图形填充的思路
Feb 02 Python
使用Python3 poplib模块删除服务器多天前的邮件实现代码
Apr 24 Python
win7上tensorflow2.2.0安装成功 引用DLL load failed时找不到指定模块 tensorflow has no attribute xxx 解决方法
May 20 Python
Python 用__new__方法实现单例的操作
Dec 11 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
简单了解PHP编程中数组的指针的使用
2015/11/30 PHP
php远程下载类分享
2016/04/13 PHP
php使用number_format函数截取小数的方法分析
2016/05/27 PHP
curl 出现错误的调试方法(必看)
2017/02/13 PHP
php实现不通过扩展名准确判断文件类型的方法【finfo_file方法与二进制流】
2017/04/18 PHP
js监听表单value的修改同步问题,跨浏览器支持
2009/12/31 Javascript
js中判断用户输入的值是否为空的简单实例
2013/12/23 Javascript
window.location 对象所包含的属性
2014/10/10 Javascript
JavaScript截取指定长度字符串点击可以展开全部代码
2015/12/04 Javascript
微信小程序 地图(map)实例详解
2016/11/16 Javascript
Jquery Easyui分割按钮组件SplitButton使用详解(17)
2016/12/18 Javascript
微信小程序 省市区选择器实例详解(附源码下载)
2017/01/05 Javascript
一篇看懂vuejs的状态管理神器 vuex状态管理模式
2017/04/20 Javascript
基于Bootstrap框架菜鸟入门教程(推荐)
2017/09/17 Javascript
解决angular双向绑定无效果,ng-model不能正常显示的问题
2018/10/02 Javascript
微信小程序实现留言功能
2018/10/31 Javascript
js 获取本周、上周、本月、上月、本季度、上季度的开始结束日期
2020/02/01 Javascript
python获取Linux下文件版本信息、公司名和产品名的方法
2014/10/05 Python
Python模拟登陆淘宝并统计淘宝消费情况的代码实例分享
2016/07/04 Python
Python实现读取文件最后n行的方法
2017/02/23 Python
对python实现二维函数高次拟合的示例详解
2018/12/29 Python
python机器人运动范围问题的解答
2019/04/29 Python
Python任务自动化工具tox使用教程
2020/03/17 Python
css3.0 图形构成实例练习一
2013/03/19 HTML / CSS
Canvas与图片压缩的示例代码
2017/11/28 HTML / CSS
Under Armour西班牙官网:美国知名的高端功能性运动品牌
2018/12/12 全球购物
洛佩桑酒店官方网站:Lopesan Hotels
2019/04/15 全球购物
办公室前台岗位职责
2014/01/04 职场文书
2014年计算机专业个人自我评价
2014/01/19 职场文书
工作表现自我评价
2014/02/08 职场文书
2014年最新大专生职业生涯规划书范文
2014/09/13 职场文书
新学期红领巾广播稿
2014/10/04 职场文书
2016年校园社会综合治理宣传月活动总结
2016/03/16 职场文书
python如何进行基准测试
2021/04/26 Python
SQL语法CONSTRAINT约束操作详情
2022/01/18 MySQL
剖析后OpLog订阅MongoDB的数据变更就没那么难了
2022/02/24 MongoDB