SocketServer的使用

SocketServer内部使用IO多路复用以及"多线程"和"多进程",从而实现并发处理多个客户端请求的socket服务端。即:每个客户端请求连接服务器时,socket服务端都会在服务器是创建一个“线程”或“进程”专门负责处理当前客户的所有请求。

注意:导入模块的时候3.x是socketserver,2.x是SocketServer。

它的工作机制如下:

 

1 虽然用python编写简单的网络程序很方法,但复杂点的网络程序还是用线程的框架比较好。这样就可以专心事物逻辑,而不是套接字的各种细节。

socketserver模块简化了编程网络服务程序的任务。同时socketserver模块也是简化了编写网络服务程序的任务。同时sockerserver模块也是python标准库中很多服务器框架的基础。

注意:在socket编程中,如果想重用一个IP地址,可以使用:

  server = socket.socket()

  server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

2 网络服务类:

  socketserver提供了4个基本的服务类。

  TCPServer 针对TCP套接字流、UDPServer针对UDP数据报套接字、UnixStreamServer和UnixDatagramServer针对UNIX域套接字,不常用。

   这四个服务类都是同步处理请求的,一个请求没处理完不能处理下一个请求。要想支持异步模型,可以使用多继承让server类继承ForkingMixIn或ThreadingMixIn,利用多进程或多线程实现异步。

  要实现一项服务,还必须派生一个handler class请求处理类,并重写父类的handler()方法。handler方法就是用来专门处理请求的。该模块是通过服务类和请求处理类组合来处理请求的。

  需要实现并发,必须使用以下一个多并发的类

  class socketserver.ForkingTCPServer

  class socketserver.ForkingUDPServer

  class socketserver.ThreadingTCPServer

       class socketserver.ThreadingUDPServer

3 ThreadingTCPServer实现的socket服务器内部会为每个client创建一个"线程",该线程用来和客户端进行交互。创建一个继承自socketserver.BaseRequestHandler的类,类中必须定义一个handle的方法,通过serve_forever()来启动,通过一个程序来说明使用方法。

服务端

 1 import socketserver
 2 class MyServer(socketserver.BaseRequestHandler):
 3     def handle(self):
 4         conn = self.request
 5         conn.send("我是多线程".encode())
 6         while True:
 7             try:
 8                 data = conn.recv(1024)
 9                 print(data,type(data))
10                 if data.decode() == "exit":
11                     break
12                 elif data.decode() == '0':
13                     conn.send("您输入的是0".encode())
14                 else:
15                     conn.send("请重新输入".encode())
16             except ConnectionRefusedError as e:
17                 print("err",e)
18                 break
19 if __name__ == "__main__":
20     server = socketserver.ThreadingTCPServer(("127.0.0.1",8080),MyServer)
21     server.serve_forever()
View Code

客户端

 1 import socket
 2 ip_port = ('127.0.0.1',8080)
 3 sk = socket.socket()
 4 sk.connect(ip_port)
 5 while True:
 6     data = sk.recv(1024)
 7     print ('receive:',data.decode())
 8     inp = input('please input:')
 9     sk.sendall(inp.encode())
10     if inp == 'exit':
11         break
12 sk.close()
View Code

 4 socketserver.BaserServer(server_address,requestHandlerClass)主要有以下方法:

class socketserver.BaseServer(server_address, RequestHandlerClass)
This is the superclass of all Server objects in the module. It defines the interface, given below, but does not implement most of the methods, which is done in subclasses. The two parameters are stored in the respective server_address and RequestHandlerClass attributes.

fileno()
Return an integer file descriptor for the socket on which the server is listening. This function is most commonly passed to selectors, to allow monitoring multiple servers in the same process.

handle_request()
Process a single request. This function calls the following methods in order: get_request(), verify_request(), and process_request(). If the user-provided handle() method of the handler class raises an exception, the server’s handle_error() method will be called. If no request is received within timeout seconds, handle_timeout() will be called and handle_request() will return.

serve_forever(poll_interval=0.5)
Handle requests until an explicit shutdown() request. Poll for shutdown every poll_interval seconds. Ignores the timeout attribute. It also calls service_actions(), which may be used by a subclass or mixin to provide actions specific to a given service. For example, the ForkingMixIn class uses service_actions() to clean up zombie child processes.

Changed in version 3.3: Added service_actions call to the serve_forever method.

service_actions()
This is called in the serve_forever() loop. This method can be overridden by subclasses or mixin classes to perform actions specific to a given service, such as cleanup actions.

New in version 3.3.

shutdown()
Tell the serve_forever() loop to stop and wait until it does.

server_close()
Clean up the server. May be overridden.

address_family
The family of protocols to which the server’s socket belongs. Common examples are socket.AF_INET and socket.AF_UNIX.

RequestHandlerClass
The user-provided request handler class; an instance of this class is created for each request.

server_address
The address on which the server is listening. The format of addresses varies depending on the protocol family; see the documentation for the socket module for details. For Internet protocols, this is a tuple containing a string giving the address, and an integer port number: ('127.0.0.1', 80), for example.

socket
The socket object on which the server will listen for incoming requests.

The server classes support the following class variables:

allow_reuse_address
Whether the server will allow the reuse of an address. This defaults to False, and can be set in subclasses to change the policy.

request_queue_size
The size of the request queue. If it takes a long time to process a single request, any requests that arrive while the server is busy are placed into a queue, up to request_queue_size requests. Once the queue is full, further requests from clients will get a “Connection denied” error. The default value is usually 5, but this can be overridden by subclasses.

socket_type
The type of socket used by the server; socket.SOCK_STREAM and socket.SOCK_DGRAM are two common values.

timeout
Timeout duration, measured in seconds, or None if no timeout is desired. If handle_request() receives no incoming requests within the timeout period, the handle_timeout() method is called.

There are various server methods that can be overridden by subclasses of base server classes like TCPServer; these methods aren’t useful to external users of the server object.

finish_request()
Actually processes the request by instantiating RequestHandlerClass and calling its handle() method.

get_request()
Must accept a request from the socket, and return a 2-tuple containing the new socket object to be used to communicate with the client, and the client’s address.

handle_error(request, client_address)
This function is called if the handle() method of a RequestHandlerClass instance raises an exception. The default action is to print the traceback to standard output and continue handling further requests.

handle_timeout()
This function is called when the timeout attribute has been set to a value other than None and the timeout period has passed with no requests being received. The default action for forking servers is to collect the status of any child processes that have exited, while in threading servers this method does nothing.

process_request(request, client_address)
Calls finish_request() to create an instance of the RequestHandlerClass. If desired, this function can create a new process or thread to handle the request; the ForkingMixIn and ThreadingMixIn classes do this.

server_activate()
Called by the server’s constructor to activate the server. The default behavior for a TCP server just invokes listen() on the server’s socket. May be overridden.

server_bind()
Called by the server’s constructor to bind the socket to the desired address. May be overridden.

verify_request(request, client_address)
Must return a Boolean value; if the value is True, the request will be processed, and if it’s False, the request will be denied. This function can be overridden to implement access controls for a server. The default implementation always returns True.

socketserver.BaseServer

 

posted @ 2017-08-17 17:20  会开车的好厨师  阅读(324)  评论(0)    收藏  举报