python 网络编程之socketserver模块

前言:(以下是基于我学习完python核心编程之网络编程篇章的个人知识输出,知识不算齐全,想深入的可自己再查阅书籍)

虽说用Python编写简单的网络程序很方便,但复杂一点的网络程序还是用现成的框架比较好。这样就可以专心事务逻辑,而不是套接字的各种细节。SocketServer模块简化了编写网络服务程序的任务。同时SocketServer模块也是Python标准库中很多服务器框架的基础。

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 


2.网络服务类:

SocketServer提供了4个基本的服务类:

TCPServer针对TCP套接字流

UDPServer针对UDP数据报套接字

UnixStreamServer和UnixDatagramServer针对UNIX域套接字,不常用。

它们的继承关系如下:

+------------+

| BaseServer |

+------------+

     |

     v

+-----------+        +------------------+

| TCPServer |------->| UnixStreamServer |

+-----------+        +------------------+

     |

     v

+-----------+        +--------------------+

| UDPServer |------->| UnixDatagramServer |

+-----------+        +--------------------+

2.1异步处理:

这个四个服务类都是同步处理请求的。一个请求没处理完不能处理下一个请求。要想支持异步模型,可以利用多继承让server类继承ForkingMixIn 或 ThreadingMixIn mix-in classes。

ForkingMixIn利用多进程(分叉)实现异步。

ThreadingMixIn利用多线程实现异步。

3.请求处理类:

要实现一项服务,还必须派生一个handler class请求处理类,并重写父类的handle()方法。handle方法就是用来专门是处理请求的。该模块是通过服务类和请求处理类组合来处理请求的。

SocketServer模块提供的请求处理类有BaseRequestHandler,以及它的派生类StreamRequestHandler和DatagramRequestHandler。从名字看出可以一个处理流式套接字,一个处理数据报套接字。

4.总结用SocketServer创建一个服务的步骤:

1.创建一个request handler class(请求处理类),继承自BaseRequestHandler class并重写它的handle()方法,该方法将处理到的请求。

2.实例化一个server class对象,并将服务的地址和之前创建的request handler class传递给它。

3.调用server class对象的handle_request() 或 serve_forever()方法来开始处理请求。


创建一个socketserverTCP服务器

[python]  view plain  copy
  1. from socketserver import (TCPServer as TCP, StreamRequestHandler as SRH)    #可以通过as起别名  
  2. from time import ctime  
  3.    
  4. HOST = ''  
  5. PORT = 1234  
  6. ADDR = (HOST, PORT)  
  7.   
  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.   
  13.   
  14. tcpServ = TCP(ADDR, MyRequestHandler)  
  15. print ('等待新的连接。。。。')  
  16.   
  17. tcpServ.serve_forever()  
我们从socketserver的StreamRequestHandler类中派生出一个子类,并重写handle()函数。在BaseRequest 类中,这个函数什么也不做。 在有客户消息进来的时候,handle()函数就会被调用 。StreamRequestHandler 类支持 像操作文件对象那样操作输入输出套接字 。我们可以用 readline()函数得到客户消息 ,用 write()函数 把字符串发给客户。

创建一个socketserverTCP客户端

[python]  view plain  copy
  1. #coding=UTF-8  
  2. from socket import *  
  3. import sys  
  4. reload (sys)  
  5. sys.setdefaultencoding('utf8')     
  6.   
  7. HOST = '192.168.1.27'  
  8. PORT = 1234  
  9. BUFSIZE = 1024  
  10. ADDR = (HOST, PORT)  
  11.   
  12. while True:  
  13.     tcpCliSock = socket(AF_INET, SOCK_STREAM)  
  14.     tcpCliSock.connect(ADDR)  
  15.     data = raw_input('>')  
  16.     if not data:  
  17.         break  
  18.     tcpCliSock.send('%s\r\n' % data.encode("UTF-8"))  
  19.     data = tcpCliSock.recv(BUFSIZE).decode("UTF-8")  
  20.     if not data:  
  21.         break  
  22.     print (data.strip())  
  23.     tcpCliSock.close()  
因为这里使用的处理程序类对待套接字通信就像文件一样,所以必须发送终止符(回车和换行符)


你可能感兴趣的:(Python)