代码改变世界

网络编程之socketserver

2018-02-23 11:01  親親宝贝  阅读(311)  评论(0编辑  收藏  举报
网络编程之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相关业务逻辑
"""
View Code

 

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来选择对应的业务逻辑类来处理