• python网络编程之socket(二)


    socketserver

    socketserver

    socket并不能多并发,只能支持一个用户。socketserver则实现了并发处理。当有多个客户端连接时,socketserver都会在服务器上创建一个线程或进程来处理该客户端的请求,一个客户端对应一个服务端的进程或线程,这样增加系统的利用率。
    socketserver是socket的封装,简化了编写网络服务程序的任务。python2中为SocketServer,python3中取消了首字母大写,改为socketserver。

    socketserver中包含了两种类,一种为服务类(server class),一种为请求处理类(request handle
    class)。前者提供了许多方法,像绑定、监听、运行(建立连接的过程),后者则专注于如何处理用户所发送的数据(事务逻辑)。一般情况下,所有的服务都是先建立连接(也就是建立服务类的实例),然后开始处理用户请求(也就是建立请求处理类的实例)。

    socketserver有4个类,分别是TCPServer、UDPServer、UnixStreamServer和UnixDatagramServer。

    1. class socketserver.TCPServer(server_address, RequestHandlerClass, bind_and_activate=True)
      TCP协议
    2. class socketserver.UDPServer(server_address, RequestHandlerClass, bind_and_activate=True)
      UDP协议,传输过程中可能会造成数据丢失等情况。
    3. class socketserver.UnixStreamServer(server_address, RequestHandlerClass, bind_and_activate=True)
      tcp协议,用于unix机器的进程间通信,不可用于windows主机。
    4. class socketserver.UnixDatagramServer(server_address, RequestHandlerClass, bind_and_activate=True)
      udp协议,用于unix机器的进程间通信,不可用于windows主机。
      继承关系
    +------------+
    | BaseServer |
    +------------+
    |
    v
    +-----------+ +------------------+
    | TCPServer |------->| UnixStreamServer |
    +-----------+ +------------------+
    |
    v
    +-----------+ +--------------------+
    | UDPServer |------->| UnixDatagramServer |
    +-----------+ +--------------------+

    上述的4个类用于处理同步的请求,也就是当前请求必须处理完成才能开始下一个请求。不适用于单个请求处理时间很长的情况。
    单个请求处理需要很长时间的情况,可以创建一个单独的线程或进程去处理每个请求,ForkingMixIn和ThreadingMixIn类支持异步请求。
    当从ThreadingMixIn继承线程连接时,应该明确声明线程意外关闭时的行为。ThreadingMixIn类中定义了一个属性daemon_threads,它用来标识服务器是否等待线程终止。如果希望线程自动执行,应该明确设置标识,默认情况下是False,也就是python将会在ThreadingMixIn创建的所有线程都退出之后才退出。
    不论采用何种协议,服务类(server class)的外部方法和属性都是相同的。

    创建

    1. 创建一个请求处理类,并且这个类要继承BaseRequsetHandler类,重写父类的handle()方法。
    2. 实例化一个服务类,并给它传递服务端IP地址和上面的请求处理类。推荐在server使用with语句。
    3. 调用服务对象的handle_request()或者server_forever()方法,前者用于处理一个请求,后者用于处理多个请求。
    4. 调用server_close()关闭socket(使用with语句则不需要)。
      实例
      服务端
    import socketserver
    class MyTcpHandler(socketserver.BaseRequestHandler):
    def handle(self):
    while True:
    try:
    self.data = self.request.recv(1024).strip()
    print("{} wrote:".format(self.client_address[0]), end=" ")
    print(self.data)
    self.request.sendall(self.data.upper())
    except ConnectionResetError as e:
    print("err ", e)
    break
    if __name__ == "__main__":
    HOST, PORT = "localhost", 9999
    with socketserver.ThreadingTCPServer((HOST, PORT), MyTcpHandler) as server:
    server.serve_forever()

    客户端

    import socket
    client = socket.socket()
    client.connect(('localhost', 9999))
    while True:
    msg = input(">>>").strip()
    if len(msg) ==0:continue
    client.send(msg.encode("utf-8"))
    data = client.recv(1024)
    print("recv:>",data.decode())
    client.close()
    I am a slow walker,but I never walk backwards.
  • 相关阅读:
    OrCAD原理图封装规则
    web的脚本安全-CSRF
    web的脚本安全-XSS
    数据库中左右连接
    如何解决Java.lang.NoClassDefFoundError
    css垂直居中
    网上免费的web service地址
    JS 正则表达式用法
    jQuery实现滚动条向下拉到一定的程度,然后这层就一直占着不管滚动条如何向下拉都不动了的效果
    Robot Framework + Selenium2Library环境下,结合Selenium Grid实施分布式自动化测试
  • 原文地址:https://www.cnblogs.com/jiangshanwang/p/9146857.html
Copyright © 2020-2023  润新知