Python SocketServer模块 Python SocketServer模块

Python SocketServer模块

 
  • SocketServer功能:实现并发处理,就是将socket在封装,使得遍的更简单。

类型:

 
#TCPserver:TCP的socketserver。
class socketserver.TCPServer(server_address,RequestHandlerClass, bind_and_activate=True) 

#UDPserver:UDP的socketserver。
class socketserver.UDPServer(server_address, RequestHandlerClass, bind_and_activate=True)

#UnixStreamServer:本级之间TCP不同进程时使用。
class socketserver.UnixStreamServer(server_address, RequestHandlerClass, bind_and_activate=True)

#UnixDatagramServer:本级之间UDP不同进程时使用。
class socketserver.UnixDatagramServer(server_address, RequestHandlerClass,bind_and_activate=True)
 
上述每个类型都继承了一个基类,最终都是BaseServer类:
 
+------------+
| BaseServer |
+------------+
      |
      v
+-----------+        +------------------+
| TCPServer |------->| UnixStreamServer |
+-----------+        +------------------+
      |
      v
+-----------+        +--------------------+
| UDPServer |------->| UnixDatagramServer |
+-----------+        +--------------------+
 
  • 创建一个socketserver
 
1.创建一个请求处理类,并且这个类要继承BaseRequestHandler,并且还要重写父类里的handle()方法。
2.实例化一个TCPserver(soketServer类型)并且传递server ip 和上面创建的请求处理类,给这个TCPserver。
3.server.handle_request() #只处理一个请求,退出server.server_forever() #处理多个请求,永远执行
4.调用server_close()关闭server。

 注:handle()方法:与客户端所有的交互都是handle里完成的。
 注:MyTCPHandler()请求类:每次客户端请求都会实例化。
 
 
<创建一个基本的soketServer>

#添加socketserver模块
import socketserver 

#处理请求类,继承BaseRequestHandler
class MyTCPHandler(socketserver.BaseRequestHandler): 

    #重写父类的handle方法
    def handle(self): 
        
        #循环处理Client请求
        while True:
            
            #客户端断开后会报ConnectionResetError错误
            try:

         #接收客户端send,写法self.request.recv()
               self.data = self.request.recv(1024).strip()

         #打印链接Client的IP地址
               print("{} wrote:".format(self.client_address[0]))
                
         #打印Client请求数据
         print(self.data)

         #处理并发回处理请求,写法self.request.send()
               self.request.send(self.data.upper())

        #Client断开报错处理,赋值e
            except ConnectionResetError as e:
                print("err",e)
                break

if __name__ == "__main__":
#创建服务端IP,端口
HOST, PORT = "localhost", 9999

#ForkingTCPServer:多进程,Linux可用,windows(没有os.fork(创建新进程)不可用)。
#ThreadingTCPServer:多线程,效果相同。
#实例化ThreadingTCPServer:一对多并发处理,每多一位Client多开一个独立线程。
server = socketserver.ThreadingTCPServer((HOST, PORT),MyTCPHandler)
    
#实例化TCPServer:一对一的请求处理。
#server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)

#执行服务端
server.serve_forever()
 

class socketserver.BaseServer(server_address, RequestHandlerClass)
#这是模块中所有服务器对象的超类。它定义了下面给出的接口,但是并没有实现大多数方法,这些方法都是在子类中完成的。这两个参数存储在各自的server_address和RequestHandlerClass属性中。

fileno()
#返回服务器正在监听的套接字的整数文件描述符。这个函数通常被传递给选择器,以便在相同的进程中监视多个服务器。

handle_request()
#处理一个请求。该函数调用以下方法:get_request()、verify_request()和process_request()。如果处理程序类的用户提供的handle()方法引发异常,则调用服务器的handle_error()方法。如果在超时时间内没有收到请求,将调用handle_timeout()并返回handle_request()。

serve_forever(poll_interval=0.5)
#处理请求,直到显式关闭()请求。轮询关闭每个poll_interval秒。忽略了超时属性。它还调用service_actions(),它可以被子类或mixin使用,以提供特定于给定服务的操作。例如,ForkingMixIn类使用service_actions()来清理僵尸进程。

service_actions()
#这在serve_forever()循环中调用。该方法可以被子类或mixin类覆盖,以执行特定于给定服务的操作,例如清理操作。

shutdown()
#告诉serve_forever()循环停止并等待直到它完成。

server_close()
#清理服务器。可能会被覆盖。

address_family
#服务器套接字所属的协议族。常见的例子是套接字。AF_INET socket.AF_UNIX。

RequestHandlerClass
#用户提供的请求处理程序类;为每个请求创建该类的一个实例。

server_address
#服务器正在监听的地址。地址的格式取决于协议族;详细信息请参阅套接字模块的文档。对于Internet协议,这是一个包含给出地址的字符串的元组,以及一个整数端口号(例如:“127.0.0.1”,80)。

allow_reuse_address
#服务器是否允许重用地址。此缺省值为False,可以在子类中设置更改策略。

request_queue_size
#请求队列的大小。如果需要很长时间来处理单个请求,当服务器繁忙时到达的任何请求都被放置到队列中,直到request_queue_size请求。一旦队列满了,来自客户端的进一步请求将会得到一个“拒绝连接”错误。默认值通常是5,但这可以被子类覆盖。

socket_type
#服务器使用的套接字的类型;套接字。SOCK_STREAM套接字。SOCK_DGRAM是两个常见的值。
#超时时间,以秒为单位,如果不需要超时,则为零。如果handle_request()在超时时间内没有收到传入请求,则调用handle_timeout()方法。

finish_request()
#实际上,通过实例化RequestHandlerClass并调用它的handle()方法来处理请求。

get_request()
#必须接受来自套接字的请求,并返回一个包含新套接字对象的2元组,用于与客户端进行通信,以及客户端的地址。

client_address handle_error(请求)
#如果RequestHandlerClass实例的handle()方法引发异常,则调用此函数。默认的操作是将traceback打印到标准输出,并继续处理进一步的请求。

handle_timeout()
#当超时属性被设置为其他值时,该函数被调用,超时时间已经过去,没有收到任何请求。forking服务器的默认动作是收集已退出的任何子进程的状态,而在线程服务器中,此方法什么都不做。

client_address process_request(请求)
#调用finish_request()来创建RequestHandlerClass的实例。如果需要,这个函数可以创建一个新的进程或线程来处理请求;ForkingMixIn和ThreadingMixIn类这样做。

server_activate()
#由服务器的构造函数调用来激活服务器。TCP服务器的默认行为只是在服务器的套接字上调用listen()。可能会被覆盖。

server_bind()
#由服务器的构造函数调用,以将套接字绑定到所需的地址。可能会被覆盖。

client_address verify_request(请求)
#必须返回一个布尔值;如果值为真,请求将被处理,如果是错误的,请求将被拒绝。可以重写此函数来实现服务器的访问控制。默认的实现总是返回True

test

  • SocketServer功能:实现并发处理,就是将socket在封装,使得遍的更简单。

类型:

 
#TCPserver:TCP的socketserver。
class socketserver.TCPServer(server_address,RequestHandlerClass, bind_and_activate=True) 

#UDPserver:UDP的socketserver。
class socketserver.UDPServer(server_address, RequestHandlerClass, bind_and_activate=True)

#UnixStreamServer:本级之间TCP不同进程时使用。
class socketserver.UnixStreamServer(server_address, RequestHandlerClass, bind_and_activate=True)

#UnixDatagramServer:本级之间UDP不同进程时使用。
class socketserver.UnixDatagramServer(server_address, RequestHandlerClass,bind_and_activate=True)
 
上述每个类型都继承了一个基类,最终都是BaseServer类:
 
+------------+
| BaseServer |
+------------+
      |
      v
+-----------+        +------------------+
| TCPServer |------->| UnixStreamServer |
+-----------+        +------------------+
      |
      v
+-----------+        +--------------------+
| UDPServer |------->| UnixDatagramServer |
+-----------+        +--------------------+
 
  • 创建一个socketserver
 
1.创建一个请求处理类,并且这个类要继承BaseRequestHandler,并且还要重写父类里的handle()方法。
2.实例化一个TCPserver(soketServer类型)并且传递server ip 和上面创建的请求处理类,给这个TCPserver。
3.server.handle_request() #只处理一个请求,退出server.server_forever() #处理多个请求,永远执行
4.调用server_close()关闭server。

 注:handle()方法:与客户端所有的交互都是handle里完成的。
 注:MyTCPHandler()请求类:每次客户端请求都会实例化。
 
 
<创建一个基本的soketServer>

#添加socketserver模块
import socketserver 

#处理请求类,继承BaseRequestHandler
class MyTCPHandler(socketserver.BaseRequestHandler): 

    #重写父类的handle方法
    def handle(self): 
        
        #循环处理Client请求
        while True:
            
            #客户端断开后会报ConnectionResetError错误
            try:

         #接收客户端send,写法self.request.recv()
               self.data = self.request.recv(1024).strip()

         #打印链接Client的IP地址
               print("{} wrote:".format(self.client_address[0]))
                
         #打印Client请求数据
         print(self.data)

         #处理并发回处理请求,写法self.request.send()
               self.request.send(self.data.upper())

        #Client断开报错处理,赋值e
            except ConnectionResetError as e:
                print("err",e)
                break

if __name__ == "__main__":
#创建服务端IP,端口
HOST, PORT = "localhost", 9999

#ForkingTCPServer:多进程,Linux可用,windows(没有os.fork(创建新进程)不可用)。
#ThreadingTCPServer:多线程,效果相同。
#实例化ThreadingTCPServer:一对多并发处理,每多一位Client多开一个独立线程。
server = socketserver.ThreadingTCPServer((HOST, PORT),MyTCPHandler)
    
#实例化TCPServer:一对一的请求处理。
#server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)

#执行服务端
server.serve_forever()
 

猜你喜欢

转载自www.cnblogs.com/leijiangtao/p/11957609.html