socketserver(在Python2.*中的是SocketServer模块)是标准库中一个高级别的模块。用于简化网络客户与服务器的实现(在前面使用socket的过程中,我们先设置了socket的类型,然后依次调用bind(),listen(),accept(),最后使用while循环来让服务器不断的接受请求。而这些步骤可以通过SocketServer包来简化。)。模块中,已经实现了一些可供使用的类。

我们将再次实现之前的那个基本TCP的例子。你会注意到新实现与之前有很多相似之处,但你也要注意到,现在很多繁杂的事情已经被封装好了,你不用再去关心那个样板代码了。例子给出的是一个最简单的同步服务器。

为了要隐藏实现的细节。我们现在写程序时会使用类,这是与之前代码的另一个不同。用面向对象的方法可以帮助我们更好的组织数据与逻辑功能。你也会注意到,我们的程序现在是“事件驱动”了。这就意味着,只有在事件出现的时候,程序才有“反应”。

在之前的服务循环中,我们阻塞等待请求,有请求来的时候就处理请求,然后再回去继续等待。现在的服务循环中,就不用在服务器里写代码了,改成定义一个处理器,服务器在收到进来的请求的时候,可以调用你的处理函数。

类                 描述

BaseServer               包含服务器的核心功能与混合(mix-in)类的钩子功能。这个类用于派生,不要直接生成这个类的类对象,可以考虑使用 TCPServer 和UDPServer。 
TCPServer/UDPServer     基本的网络同步 TCP/UDP 服务器 
UnixStreamServer/            基本的基于文件同步 TCP/UDP 服务器 
UnixDatagramServer 
ForkingMixIn/                      实现了核心的进程化或线程化的功能,用于与服务器类进行混合(mix-in),以提供一些异步特性。 
ThreadingMixIn                  不要直接生成这个类的对象 
ForkingTCPServer/            ForkingMixIn 和 TCPServer/UDPServer 的组合 
ForkingUDPServer 
ThreadingTCPServer/       ThreadingMixIn 和 TCPServer/UDPServer 的组合 
ThreadingUDPServer 
BaseRequestHandler       包含处理服务请求的核心功能。只用于派生新的类,不要直接生成这个类的对象,可以考虑使用 StreamRequestHandler 或DatagramRequestHandler 
StreamRequestHandler/   TCP/UDP 服务器的请求处理类的一个实现 
DatagramRequestHandler

创建一个socketserverTCP服务器

  1. from socketserver import (TCPServer as TCP, StreamRequestHandler as SRH)    #可以通过as起别名
  2. from time import ctime
  3. HOST = ''
  4. PORT = 1234
  5. ADDR = (HOST, PORT)
  6. class MyRequestHandler(SRH):
  7. def handle(self):
  8. print ('已经连接:', self.client_address)
  9. self.wfile.write(('[%s] %s' % (ctime(), self.rfile.readline().decode("UTF-8"))).encode("UTF-8"))
  10. tcpServ = TCP(ADDR, MyRequestHandler)
  11. print ('等待新的连接。。。。')
  12. tcpServ.serve_forever()

我们从socketserver的StreamRequestHandler类中派生出一个子类,并重写handle()函数。在BaseRequest 类中,这个函数什么也不做。在有客户消息进来的时候,handle()函数就会被调用。StreamRequestHandler 类支持像操作文件对象那样操作输入输出套接字。我们可以用readline()函数得到客户消息,用write()函数把字符串发给客户。

创建一个socketserverTCP客户端

  1. #coding=UTF-8
  2. from socket import *
  3. import sys
  4. reload (sys)
  5. sys.setdefaultencoding('utf8')
  6. HOST = '192.168.1.27'
  7. PORT = 1234
  8. BUFSIZE = 1024
  9. ADDR = (HOST, PORT)
  10. while True:
  11. tcpCliSock = socket(AF_INET, SOCK_STREAM)
  12. tcpCliSock.connect(ADDR)
  13. data = raw_input('>')
  14. if not data:
  15. break
  16. tcpCliSock.send('%s\r\n' % data.encode("UTF-8"))
  17. data = tcpCliSock.recv(BUFSIZE).decode("UTF-8")
  18. if not data:
  19. break
  20. print (data.strip())
  21. tcpCliSock.close()

使用socketserver处理多链接

上面的例子一次只能连接一个客户机并出力它的请求,如果要处理多连接问题,那么有三种主要的方法能实现这个目的:分叉(forking)、线程(threading)以及异步I/O(asynchronous I/O)。通过对socketserver服务器使用混入类(mix-in class),派生进程和线程很容易处理。即使要自己实现它们,这些方法也很容易使用。它们确实有缺点:分叉占据资源,并且如果有太多的客户端时分叉不能很好分叉(尽管如此,对于合理数量的客户端,分叉在现代的UNIX或者Linux系统中是很高效的,如果有一个多CPU系统,那系统效率会更高);线程处理能导致同步问题。使用socketserver框架创建分叉或者线程服务器非常简单:

分叉服务器:

  1. from socketserver import (TCPServer as TCP, StreamRequestHandler as SRH,ForkingMixIn as FMI)   #变动位置
  2. from time import ctime
  3. HOST = ''
  4. PORT = 1234
  5. ADDR = (HOST, PORT)
  6. class Server(FMI, TCP):                                                                         #变动位置
  7. pass
  8. class MyRequestHandler(SRH):
  9. def handle(self):
  10. print ('已经连接:', self.client_address)
  11. self.wfile.write(('[%s] %s' % (ctime(), self.rfile.readline().decode("UTF-8"))).encode("UTF-8"))
  12. tcpServ = Server(ADDR, MyRequestHandler)                                                         #变动位置
  13. print ('等待新的连接。。。。')
  14. tcpServ.serve_forever()

多线程SocketServer服务器:

  1. from socketserver import (TCPServer as TCP, StreamRequestHandler as SRH,ThreadingMixIn as TMI)   #变动位置
  2. from time import ctime
  3. HOST = ''
  4. PORT = 1234
  5. ADDR = (HOST, PORT)
  6. class Server(TMI, TCP):                                         #变动位置
  7. pass
  8. class MyRequestHandler(SRH):
  9. def handle(self):
  10. print ('已经连接:', self.client_address)
  11. self.wfile.write(('[%s] %s' % (ctime(), self.rfile.readline().decode("UTF-8"))).encode("UTF-8"))
  12. tcpServ = Server(ADDR, MyRequestHandler)                        #变动位置
  13. print ('等待新的连接。。。。')
  14. tcpServ.serve_forever()

Python网络编程03----Python3.*中socketserver的更多相关文章

  1. Python网络编程03 /缓存区、基于TCP的socket循环通信、执行远程命令、socketserver通信

    Python网络编程03 /缓存区.基于TCP的socket循环通信.执行远程命令.socketserver通信 目录 Python网络编程03 /缓存区.基于TCP的socket循环通信.执行远程命 ...

  2. Python网络编程(3)——SocketServer模块与简单并发服务器

    主要类型 该模块有四个比较主要的类,其中常用的是 TCPServer 和 UDPServer. 1. TCPServer 2. UDPServer 3. UnixStreamServer,类似于TCP ...

  3. python网络编程-TCP协议中的三次握手和四次挥手(图解)

    建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资 ...

  4. Python -- 网络编程 -- 认识Python3的urllib库

    Python3的urllib包含5个模块 urllib error parse request response robotparser 各个模块的主要成员: error ['ContentTooSh ...

  5. python网络编程应用(一)

     在之前的一篇博客<python网络编程基础>中介绍了socket.socket()函数及其应用,其实socket模块中还有很多属性可供网络应用程序使用.这里将详细讲解一下socket模块 ...

  6. Python网络编程基础 PDF 完整超清版|网盘链接内附提取码下载|

    点此获取下载地址提取码:y9u5 Python网络编程最好新手入门书籍!175个详细案例,事实胜于雄辩,Sockets.DNS.Web Service.FTP.Email.SMTP.POP.IMAP. ...

  7. python 网络编程 TCP/IP socket UDP

    TCP/IP简介 虽然大家现在对互联网很熟悉,但是计算机网络的出现比互联网要早很多. 计算机为了联网,就必须规定通信协议,早期的计算机网络,都是由各厂商自己规定一套协议,IBM.Apple和Micro ...

  8. python 网络编程:socket

    在学习socket之前,我们先复习下相关的网络知识. OSI七层模型:应用层,表示层,会话层,传输层,网络层,数据链路层,物理层.OSI七层模型是由国际标准化组织ISO定义的网络的基本结构,不仅包括一 ...

  9. 图解Python网络编程

    返回目录 本篇索引 (1)基本原理 (2)socket模块 (3)select模块 (4)asyncore模块 (5)asynchat模块 (6)socketserver模块 (1)基本原理 本篇指的 ...

  10. Python 网络编程(二)

    Python 网络编程 上一篇博客介绍了socket的基本概念以及实现了简单的TCP和UDP的客户端.服务器程序,本篇博客主要对socket编程进行更深入的讲解 一.简化版ssh实现 这是一个极其简单 ...

随机推荐

  1. 从别人那淘的知识 深入剖析Java中的装箱和拆箱

    (转载的海子的博文   海子:http://www.cnblogs.com/dolphin0520/) 深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来 ...

  2. 《C#开发微信门户及应用》

    C#开发微信门户及应用(40)--使用微信JSAPI实现微信支付功能 C#开发微信门户及应用(39)--使用微信JSSDK实现签到的功能 C#开发微信门户及应用(38)--微信摇一摇红包功能 C#开发 ...

  3. input覆盖select实现select可写可选择

    1.有时需要一个select选择框,但是对select选择框希望是既可以选择也可以进行输入.下边的代码就是在select选择框上放了一个input框,覆盖在select上面.实现伪装的select效果 ...

  4. 函数调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。

    在dllimport中加入CallingConvention参数就行了,[DllImport(PCAP_DLL, CharSet = CharSet.Auto, CallingConvention = ...

  5. js——页面回到顶部

    很久都没有去慕课网学习学习了,刚恰好就看见了一个用的比较多的小例子——页面回到顶部,记得之前自己也是在初学web时,被这个坑了一回,因此今天特地拿来分享分享…… <!DOCTYPE html&g ...

  6. android 回调的理解(结合接口)

    什么是回调 回调其实是一种双向调用模式,也就是调用方在接口被调用时也会调用对方的接口.通俗的解释为:类A调用了类B中的方法1,然后类B最后又反过来调用类A中的方法2,即把结果返回给类A. 回调的具体实 ...

  7. 转:Nginx配置指令location匹配符优先级和安全问题

    转:http://www.jb51.net/article/47761.htm 使用nginx 很久了,它的性能高,稳定性表现也很好,得到了很多人的认可.特别是它的配置,有点像写程序一样,每行命令结尾 ...

  8. mac 找文件

    如何找到 etc 方法1: ! D# D! s2 F" f 七度苹果电脑软件1.打开Finder,按快键盘 Command + Shift + G,即可调出 前往文件夹 ,也可以左上角 找到 ...

  9. redhat enterprixe 5.0 下DHCP服务器rpm安装配置及其测试

    一.了解DHCP DHCP服务提供动态指定IP地址和配置参数的机制.有动态和静态两种方式. 二.rpm安装 因为配过Samba,所以感觉挺简单. 首先找到主程序和几个附属程序的rpm的安装包.应该都是 ...

  10. java面向对象编程——第二章 java基础语法

    第二章 java基础语法 1. java关键字 abstract boolean break byte case catch char class const continue default do ...