zoukankan      html  css  js  c++  java
  • Python网络编程——SocketServer基础

    SocketServer

    The socketserver module simplifies the task of writing network servers.

    There are four basic concrete server classes:

    class socketserver.TCPServer(server_addressRequestHandlerClassbind_and_activate=True)

    This uses the Internet TCP protocol, which provides for continuous streams of data between the client and server. If bind_and_activate is true, the constructor automatically attempts to invoke server_bind() andserver_activate(). The other parameters are passed to the BaseServer base class.

    class socketserver.UDPServer(server_addressRequestHandlerClassbind_and_activate=True)

    This uses datagrams, which are discrete packets of information that may arrive out of order or be lost while in transit. The parameters are the same as for TCPServer.

    class socketserver.UnixStreamServer(server_addressRequestHandlerClassbind_and_activate=True)
    class socketserver.UnixDatagramServer(server_addressRequestHandlerClass,bind_and_activate=True)

    These more infrequently used classes are similar to the TCP and UDP classes, but use Unix domain sockets; they’re not available on non-Unix platforms. The parameters are the same as for TCPServer.

    These four classes process requests synchronously; each request must be completed before the next request can be started. This isn’t suitable if each request takes a long time to complete, because it requires a lot of computation, or because it returns a lot of data which the client is slow to process. The solution is to create a separate process or thread to handle each request; the ForkingMixIn and ThreadingMixIn mix-in classes can be used to support asynchronous behaviour.

    There are five classes in an inheritance diagram, four of which represent synchronous servers of four types:

    +------------+
    | BaseServer |
    +------------+
          |
          v
    +-----------+        +------------------+
    | TCPServer |------->| UnixStreamServer |
    +-----------+        +------------------+
          |
          v
    +-----------+        +--------------------+
    | UDPServer |------->| UnixDatagramServer |
    +-----------+        +--------------------+
    

    Note that UnixDatagramServer derives from UDPServer, not from UnixStreamServer — the only difference between an IP and a Unix stream server is the address family, which is simply repeated in both Unix server classes.

    class socketserver.ForkingMixIn
    class socketserver.ThreadingMixIn

    Forking and threading versions of each type of server can be created using these mix-in classes. For instance, ThreadingUDPServer is created as follows:

    class ThreadingUDPServer(ThreadingMixIn, UDPServer):
        pass
    

    The mix-in class comes first, since it overrides a method defined in UDPServer. Setting the various attributes also changes the behavior of the underlying server mechanism.

    class socketserver.ForkingTCPServer
    class socketserver.ForkingUDPServer
    class socketserver.ThreadingTCPServer
    class socketserver.ThreadingUDPServer

    These classes are pre-defined using the mix-in classes.

    Request Handler Objects

    class socketserver.BaseRequestHandler

    This is the superclass of all request handler objects. It defines the interface, given below. A concrete request handler subclass must define a new handle() method, and can override any of the other methods. A new instance of the subclass is created for each request.

    setup()

    Called before the handle() method to perform any initialization actions required. The default implementation does nothing.

    handle()

    This function must do all the work required to service a request. The default implementation does nothing. Several instance attributes are available to it; the request is available as self.request; the client address as self.client_address; and the server instance as self.server, in case it needs access to per-server information.

    The type of self.request is different for datagram or stream services. For stream services,self.request is a socket object; for datagram services, self.request is a pair of string and socket.

    finish()

    Called after the handle() method to perform any clean-up actions required. The default implementation does nothing. If setup() raises an exception, this function will not be called.

     server端

     1 import socketserver
     2  
     3 class MyTCPHandler(socketserver.BaseRequestHandler):
     4     """
     5     The request handler class for our server.
     6  
     7     It is instantiated once per connection to the server, and must
     8     override the handle() method to implement communication to the
     9     client.
    10     """
    11  
    12     def handle(self):
    13         # self.request is the TCP socket connected to the client
    14         self.data = self.request.recv(1024).strip()
    15         print("{} wrote:".format(self.client_address[0]))
    16         print(self.data)
    17         # just send back the same data, but upper-cased
    18         self.request.sendall(self.data.upper())
    19  
    20 if __name__ == "__main__":
    21     HOST, PORT = "localhost", 9999
    22  
    23     # Create the server, binding to localhost on port 9999
    24     server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)
    25  
    26     # Activate the server; this will keep running until you
    27     # interrupt the program with Ctrl-C
    28     server.serve_forever()

     client端

     1 import socket
     2 import sys
     3  
     4 HOST, PORT = "localhost", 9999
     5 data = " ".join(sys.argv[1:])
     6  
     7 # Create a socket (SOCK_STREAM means a TCP socket)
     8 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     9  
    10 try:
    11     # Connect to server and send data
    12     sock.connect((HOST, PORT))
    13     sock.sendall(bytes(data + "
    ", "utf-8"))
    14  
    15     # Receive data from the server and shut down
    16     received = str(sock.recv(1024), "utf-8")
    17 finally:
    18     sock.close()
    19  
    20 print("Sent:     {}".format(data))
    21 print("Received: {}".format(received))
    View Code

    上面这个例子你会发现,依然不能实现多并发,哈哈,在server端做一下更改就可以了

    1
    server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)

    改成

    1
    server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
  • 相关阅读:
    常用API及异常
    支付宝支付流程以及二次封装alipay包 支付模块后台接口的实现 订单接口实现
    课程页前台组件 课程模块的实现 表的设计及数据录入 课程详情页前台组件 课程详情页后台实现
    celery使用
    登录、注册、页头页面 手机号验证接口 发送短信接口 注册接口 多方式登录接口 手机号登录接口 发送短信接口频率限制 异常处理修订 接口缓存
    redis基础使用 python操作redis django-redis使用
    短信接口的使用(腾讯云)
    主页设计:页面头部组件 页面底部组件 轮播图组件 主页组件 主页后台: home模块创建 路由分发 Banner表的model设计 数据库迁移 注册模块
    前台vue环境配置 vue项目的创建 项目目录的重构 全局样式文件 配置文件 axios配置 cookies配置 element-ui配置 bootstrap和jquery的配置
    thinkphp6使用最新版本composer后多应用模式提示路由不存在
  • 原文地址:https://www.cnblogs.com/yz9110/p/8514556.html
Copyright © 2011-2022 走看看