网络编程之socketserver
"""
socketserver.py 中的5个基础类
+------------+
| BaseServer |
+------------+
|
v
+-----------+ +------------------+
| TCPServer |------->| UnixStreamServer |
+-----------+ +------------------+
|
v
+-----------+ +--------------------+
| UDPServer |------->| UnixDatagramServer |
+-----------+ +--------------------+
"""
socketserver简单概括
__version__ = "0.4"
import socket
import selectors
import os
import errno
import sys
try:
import threading
except ImportError:
import dummy_threading as threading
from io import BufferedIOBase
from time import monotonic as time # __all__属性由列表构成,它规定了模块的所有可见方法,会使属性列表之外的成员全部私有化。
__all__ = ["BaseServer", "TCPServer", "UDPServer",
"ThreadingUDPServer", "ThreadingTCPServer",
"BaseRequestHandler", "StreamRequestHandler",
"DatagramRequestHandler", "ThreadingMixIn"] if hasattr(os, "fork"):
__all__.extend(["ForkingUDPServer","ForkingTCPServer", "ForkingMixIn"]) if hasattr(socket, "AF_UNIX"): # 如果socket类型是AF_UNIX则将下面的添加到列表中
__all__.extend(["UnixStreamServer","UnixDatagramServer",
"ThreadingUnixStreamServer",
"ThreadingUnixDatagramServer"]) if hasattr(selectors, 'PollSelector'):
_ServerSelector = selectors.PollSelector
else:
_ServerSelector = selectors.SelectSelector class BaseServer: # 基础服务类 class TCPServer(BaseServer): # Tcp类 class UDPServer(TCPServer): # UDP类 if hasattr(os, "fork"):
class ForkingMixIn: # 提供多进程功能的类 class ThreadingMixIn: # 提供多线程功能的类 if hasattr(os, "fork"):
class ForkingUDPServer(ForkingMixIn, UDPServer): # UDP多进程类,实际就是继承了ForkingMixIn和UDPServer而已
class ForkingTCPServer(ForkingMixIn, TCPServer): # TCP多进程类,实际就是继承了ForkingMixIn和TCPServer而已 class ThreadingUDPServer(ThreadingMixIn, UDPServer): # UDP多线程类,实际就是继承了ThreadingMixIn和UDPServer而已
class ThreadingTCPServer(ThreadingMixIn, TCPServer): # TCP多线程类,实际就是继承了ThreadingMixIn和TCPServer而已 if hasattr(socket, 'AF_UNIX'): # 如果你的socket是AF_UNIX族,则定义下面4个类
class UnixStreamServer(TCPServer):
class UnixDatagramServer(UDPServer):
class ThreadingUnixStreamServer(ThreadingMixIn, UnixStreamServer):
class ThreadingUnixDatagramServer(ThreadingMixIn, UnixDatagramServer): class BaseRequestHandler: # 业务逻辑类 class StreamRequestHandler(BaseRequestHandler): # TCP相关的业务逻辑
class _SocketWriter(BufferedIOBase):
class DatagramRequestHandler(BaseRequestHandler): # UDP相关业务逻辑 """
总结:
socketserver.py 实际上就是封装了TCP服务UDP服务,多线程TCP服务,多线程UDP服务,多进程TCP服务,多进程UDP服务的类 TCPServer(BaseServer) # TCP类
UDPServer(TCPServer) # UDP类
ForkingTCPServer(ForkingMixIn, TCPServer) # 多进程TCP类
ForkingUDPServer(ForkingMixIn, UDPServer) # 多进程UDP类
ThreadingTCPServer(ThreadingMixIn, TCPServer) # 多线程TCP类
ThreadingUDPServer(ThreadingMixIn, UDPServer) # 多线程UDP类
StreamRequestHandler(BaseRequestHandler): # TCP相关的业务逻辑
DatagramRequestHandler(BaseRequestHandler): # UDP相关业务逻辑
"""
socketserver各个类之间的关系
#!/usr/bin/env python
# @Author : "Wjl"
# @Date : 2017/12/22
# @Time : 15:12
# @SoftWare : PyCharm
# @File : Test_Server.py """
通过下面的类创建基础服务:
如果是AF_INET
+-----------+ +------------------+ +--------------------+
| TCPServer |------->| ForkingTCPServer | or | ThreadingTCPServer |
+-----------+ +------------------+ +--------------------+ +-----------+ +------------------+ +--------------------+
| UDPServer |------->| ForkingUDPServer | or | ThreadingUDPServer |
+-----------+ +------------------+ +--------------------+ 如果是AF_UNIX
+----------------+ +-------------------------+
|UnixStreamServer|------->|ThreadingUnixStreamServer|
+----------------+ +-------------------------+ +------------------+ +---------------------------+
|UnixDatagramServer|------->|ThreadingUnixDatagramServer|
+------------------+ +---------------------------+ 再将你的逻辑写在如下类中的handle方法中(),传递给上面的类,来调用
+--------------------+ +----------------------+ +------------------------+
| BaseRequestHandler |------->| StreamRequestHandler | or | DatagramRequestHandler |
+--------------------+ +----------------------+ +------------------------+ """
import socketserver class MyServer(socketserver.StreamRequestHandler): # 继承业务逻辑类
def handle(self): # 将你的业务逻辑写在handle方法中
print("服务端启动...")
while True:
conn = self.request # self.request就是客户端的socket对象
print(self.client_address) # self.client_address就是客户端地址元组
while True:
client_data = conn.recv(1024)
print(str(client_data, "utf8"))
print("waiting...")
conn.sendall(client_data)
conn.close() if __name__ == '__main__':
server = socketserver.TCPServer(('127.0.0.1', 8888), MyServer) # 创建TCP服务,将业务逻辑传递给它,好让服务和业务逻辑关联起来
server.serve_forever() # 通过forever()方法来接收请求,其实就是调用了socket.accept方法
# server.handle_request() # 还可以调用handle_request()来处理请求
总结:
想要玩转socketserver
1.首先需要明确使用什么地址簇, 是 AF_INET还是UX_INET
2.明确是使用TCP还是UDP,以此来确定是使用哪个类
3.明确有没有用到多线程或多进程
4.根据2来选择对应的业务逻辑类来处理