zoukankan      html  css  js  c++  java
  • Python3 socketserver模块

     

           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服务器

    [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 ' % 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()  

    使用socketserver处理多链接


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

    分叉服务器:

     

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

    多线程SocketServer服务器:

    [python] view plain copy
     
    1. from socketserver import (TCPServer as TCP, StreamRequestHandler as SRH,ThreadingMixIn as TMI)   #变动位置  
    2. from time import ctime  
    3.    
    4. HOST = ''  
    5. PORT = 1234  
    6. ADDR = (HOST, PORT)  
    7. class Server(TMI, TCP):                                         #变动位置  
    8.     pass  
    9.   
    10. class MyRequestHandler(SRH):  
    11.     def handle(self):  
    12.         print ('已经连接:', self.client_address)  
    13.         self.wfile.write(('[%s] %s' % (ctime(), self.rfile.readline().decode("UTF-8"))).encode("UTF-8"))  
    14.   
    15.   
    16. tcpServ = Server(ADDR, MyRequestHandler)                        #变动位置  
    17. print ('等待新的连接。。。。')  
    18. tcpServ.serve_forever()  
  • 相关阅读:
    hdu 4638 Group 线段树
    hdu 4635 Strongly connected 强连通分量
    hdu 4604 Deque
    hdu 1000 A + B Problem
    数组相关
    文本文件相关
    硬件电路中VCC,VDD,VEE,VSS有什么区别
    VIPM链接LabVIEW问题
    Touch实现轻扫
    touchesMoved 实现拖拽
  • 原文地址:https://www.cnblogs.com/nuomin/p/7886950.html
Copyright © 2011-2022 走看看