python--socket编程进阶
SocketServer
The socketserver module simplifies the task of writing network servers.
There are four basic concrete server classes:
- class
socketserver.TCPServer(server_address, RequestHandlerClass, bind_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 theBaseServerbase class.
- class
socketserver.UDPServer(server_address, RequestHandlerClass, bind_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_address, RequestHandlerClass, bind_and_activate=True) - class
socketserver.UnixDatagramServer(server_address, RequestHandlerClass,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,
ThreadingUDPServeris created as follows:class ThreadingUDPServer(ThreadingMixIn, UDPServer): passThe 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.BaseRequestHandlerThis 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 asself.client_address; and the server instance asself.server, in case it needs access to per-server information.The type of
self.requestis different for datagram or stream services. For stream services,self.requestis a socket object; for datagram services,self.requestis a pair of string and socket.
finish()-
Called after the
handle()method to perform any clean-up actions required. The default implementation does nothing. Ifsetup()raises an exception, this function will not be called.socketserver.TCPServerExampleserver side
12345678910111213141516171819202122232425262728importsocketserverclassMyTCPHandler(socketserver.BaseRequestHandler):"""The request handler class for our server.It is instantiated once per connection to the server, and mustoverride the handle() method to implement communication to theclient."""defhandle(self):# self.request is the TCP socket connected to the clientself.data=self.request.recv(1024).strip()print("{} wrote:".format(self.client_address[0]))print(self.data)# just send back the same data, but upper-casedself.request.sendall(self.data.upper())if__name__=="__main__":HOST, PORT="localhost",9999# Create the server, binding to localhost on port 9999server=socketserver.TCPServer((HOST, PORT), MyTCPHandler)# Activate the server; this will keep running until you# interrupt the program with Ctrl-Cserver.serve_forever()client side
123456789101112131415161718192021importsocketimportsysHOST, PORT="localhost",9999data=" ".join(sys.argv[1:])# Create a socket (SOCK_STREAM means a TCP socket)sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)try:# Connect to server and send datasock.connect((HOST, PORT))sock.sendall(bytes(data+"\n","utf-8"))# Receive data from the server and shut downreceived=str(sock.recv(1024),"utf-8")finally:sock.close()print("Sent: {}".format(data))print("Received: {}".format(received))上面这个例子你会发现,依然不能实现多并发,哈哈,在server端做一下更改就可以了
把
1server=socketserver.TCPServer((HOST, PORT), MyTCPHandler)改成
1server=socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)SocketServer
The
socketservermodule simplifies the task of writing network servers.There are four basic concrete server classes:
- class
socketserver.TCPServer(server_address, RequestHandlerClass, bind_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 theBaseServerbase class.
- class
socketserver.UDPServer(server_address, RequestHandlerClass, bind_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_address, RequestHandlerClass, bind_and_activate=True) - class
socketserver.UnixDatagramServer(server_address, RequestHandlerClass,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
ForkingMixInandThreadingMixInmix-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
UnixDatagramServerderives fromUDPServer, not fromUnixStreamServer— 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,
ThreadingUDPServeris created as follows:class ThreadingUDPServer(ThreadingMixIn, UDPServer): passThe 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.BaseRequestHandlerThis 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 asself.client_address; and the server instance asself.server, in case it needs access to per-server information.The type of
self.requestis different for datagram or stream services. For stream services,self.requestis a socket object; for datagram services,self.requestis a pair of string and socket.
finish()-
Called after the
handle()method to perform any clean-up actions required. The default implementation does nothing. Ifsetup()raises an exception, this function will not be called.socketserver.TCPServerExampleserver side
12345678910111213141516171819202122232425262728importsocketserverclassMyTCPHandler(socketserver.BaseRequestHandler):"""The request handler class for our server.It is instantiated once per connection to the server, and mustoverride the handle() method to implement communication to theclient."""defhandle(self):# self.request is the TCP socket connected to the clientself.data=self.request.recv(1024).strip()print("{} wrote:".format(self.client_address[0]))print(self.data)# just send back the same data, but upper-casedself.request.sendall(self.data.upper())if__name__=="__main__":HOST, PORT="localhost",9999# Create the server, binding to localhost on port 9999server=socketserver.TCPServer((HOST, PORT), MyTCPHandler)# Activate the server; this will keep running until you# interrupt the program with Ctrl-Cserver.serve_forever()client side
123456789101112131415161718192021importsocketimportsysHOST, PORT="localhost",9999data=" ".join(sys.argv[1:])# Create a socket (SOCK_STREAM means a TCP socket)sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)try:# Connect to server and send datasock.connect((HOST, PORT))sock.sendall(bytes(data+"\n","utf-8"))# Receive data from the server and shut downreceived=str(sock.recv(1024),"utf-8")finally:sock.close()print("Sent: {}".format(data))print("Received: {}".format(received))多并发实现:
把
1server=socketserver.TCPServer((HOST, PORT), MyTCPHandler)改成
1server=socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
- class

浙公网安备 33010602011771号