• SocketServer模块 《Python核心编程(第3版)》——2.5


    本文内容参考文章地址:

    https://m.aliyun.com/yunqi/articles/93088/

    SocketServer模块

    SocketServer是标准库中的一个高级模块(Python 3.x中重命名为socketserver),它的目标是简化很多样板代码,它们是创建网络客户端和服务器所必需的代码。这个模块中有为你创建的各种各样的类,如表2-3所示。

    除了为你隐藏了实现细节之外,另一个不同之处是,我们现在使用类来编写应用程序。因为以面向对象的方式处理事务有助于组织数据,以及逻辑性地将功能放在正确的地方。你还会注意到,应用程序现在是事件驱动的,这意味着只有在系统中的事件发生时,它们才会工作。

    事件包括消息的发送和接收。事实上,你会看到类定义只包括一个用来接收客户端消息的事件处理程序。所有其他的功能都来自使用的SocketServer类。此外,GUI编程(见第5章)也是事件驱动的。你会立即注意到它们的相似性,因为最后一行代码通常是一个服务器的无限循环,它等待并响应客户端的服务请求。它工作起来几乎与本章前面的基础TCP服务器中的无限while循环一样。

    在原始服务器循环中,我们阻塞等待请求,当接收到请求时就对其提供服务,然后继续等待。在此处的服务器循环中,并非在服务器中创建代码,而是定义一个处理程序,这样当服务器接收到一个传入的请求时,服务器就可以调用你的函数。

    创建SocketServer TCP服务器

    首先导入服务器类,然后定义与之前相同的主机常量。其次是请求处理程序类,最后启动它。更多细节请查看下面的代码片段。

    通过使用SocketServer类、TCPServer和StreamRequestHandler,该脚本创建了一个时间戳TCP服务器。
    #!/usr/bin/env python
    
    from SocketServer import (TCPServer as TCP, StreamRequestHandler as SRH)
    from time import ctime
    
    HOST=''
    PORT=21567
    ADDR=(HOST, PORT)
    
    class MyRequestHandler(SRH):
        def handle(self):
            print '...connected from:', self.client_address
            self.wfile.write('[%s] %s'%(ctime(), self.rfile.readline()))
    
    tcpServ=TCP(ADDR, MyRequestHandler)
    print 'starting arleady!!!  waiting for connection... '
    tcpServ.serve_forever()


     

    这里面没有写客户端,因此用浏览器访问  本机的    21567    端口。

    解释:

    from SocketServer import (TCPServer as TCP, StreamRequestHandler as SRH)

     最初的部分包括从SocketServer导入正确的类。注意,这里使用了Python 2.4中引入的多行导入功能。如果使用的是较早版本的Python,那么将不得不使用完全限定的module.attribute名称,或者在同一行中导入两个属性。

    class MyRequestHandler(SRH):
        def handle(self):
            print '...connected from:', self.client_address
            self.wfile.write('[%s] %s'%(ctime(), self.rfile.readline()))

    这里进行了大量的工作。我们得到了请求处理程序MyRequestHandler,作为SocketServer中StreamRequestHandler的一个子类,并重写了它的handle()方法,该方法在基类Request中默认情况下没有任何行为。

    def handle(self):
        pass

    当接收到一个来自客户端的消息时,它就会调用handle()方法。而StreamRequestHandler类将输入和输出套接字看作类似文件的对象,因此我们将使用readline()来获取客户端消息,并利用write()将字符串发送回客户端。

    因此,在客户端和服务器代码中,需要额外的回车和换行符。实际上,在代码中你不会看到它,因为我们只是重用那些来自客户端的符号。除了这些细微的差别之外,它看起来就像以前的服务器。

     

     

     

    tcpServ=TCP(ADDR, MyRequestHandler)
    print 'starting arleady!!!  waiting for connection... '
    tcpServ.serve_forever()

    最后的代码利用给定的主机信息和请求处理类创建了TCP服务器。然后,无限循环地等待并服务于客户端请求。

    创建SocketServer TCP客户端

    这里的客户端很自然地非常像最初的客户端,比服务器像得多,但必须稍微调整它以使其与新服务器很好地工作。

    SocketServer时间戳TCP客户端(tsTclntSS.py)

    这是一个时间戳TCP客户端,它知道如何与类似文件的SocketServer类StreamRequest Handler对象通信。
    #!/usr/bin/env python
    from socket import *
    
    HOST='localhost'
    PORT=21567
    BUFSIZ=1024
    ADDR=(HOST, PORT)
    
    while True:
        tcpCliSock=socket(AF_INET, SOCK_STREAM)
        tcpCliSock.connect(ADDR)
        data=raw_input('> ')
    
        if not data:
            break
    
        tcpCliSock.send("%s
    "%data)
        data=tcpCliSock.recv(BUFSIZ)
    
        if not data:
            break
    
        print data.strip()
        tcpCliSock.close()

     

     

    SocketServer请求处理程序的默认行为是接受连接、获取请求,然后关闭连接。由于这个原因,我们不能在应用程序整个执行过程中都保持连接,因此每次向服务器发送消息时,都需要创建一个新的套接字。

    
    
  • 相关阅读:
    [BZOJ4480] JSOI2013 快乐的jyy
    [BZOJ4755] JSOI2016 扭动的回文串
    [BZOJ4754] JSOI2016 独特的树叶
    [BZOJ5179] JSOI2011 任务调度
    [BZOJ4320] SHOI2006 Homework
    [AT2300] Snuke Line
    [洛谷P3974] TJOI2015 组合数学
    [CF331E] Biologist
    [洛谷P4249] WC2007 剪刀石头布
    【BZOJ4548】小奇的糖果
  • 原文地址:https://www.cnblogs.com/devilmaycry812839668/p/8472682.html
Copyright © 2020-2023  润新知