网络编程之socketserver
"""
socketserver.py 中的5个基础类
+------------+
| BaseServer |
+------------+
|
v
+-----------+ +------------------+
| TCPServer |------->| UnixStreamServer |
+-----------+ +------------------+
|
v
+-----------+ +--------------------+
| UDPServer |------->| UnixDatagramServer |
+-----------+ +--------------------+
"""
__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相关业务逻辑
"""
#!/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来选择对应的业务逻辑类来处理
网络编程之socketserver的更多相关文章
- python3网络编程之socketserver
本节主要是讲解python3网络编程之socketserver,在上一节中我们讲到了socket.由于socket无法支持多用户和多并发,于是就有了socket server. socket serv ...
- 网络编程之socketserver初识
网络编程之socketserver初识 Server #!/usr/bin/env python # @Author : "Wjl" # @Date : 2017/12/22 # ...
- 网络编程之socketserver以及socket更多方法
关于socketserver 关于socket的更多方法 服务端套接字函数: s.bind() 绑定(主机,端口号)到套接字 s.listen() 开始tcp监听 s.accept () 被动接受tc ...
- 网络编程之socket
网络编程之socket socket:在网络编程中的一个基本组件,也称套接字. 一个套接字就是socket模块中的socket类的一个实例. 套接字包括两个: 服务器套接字和客户机套接字 套接字的实例 ...
- [深入浅出WP8.1(Runtime)]网络编程之HttpClient类
12.2 网络编程之HttpClient类 除了可以使用HttpWebRequest类来实现HTTP网络请求之外,我们还可以使用HttpClient类来实现.对于基本的请求操作,HttpClient类 ...
- java网络编程之TCP通讯
java中的网络编程之TCP协议的详细介绍,以及如何使用,同时我在下面举2例说明如何搭配IO流进行操作, /* *TCP *建立连接,形成传输数据的通道: *在连接中进行大数据量传输: *通过三次握手 ...
- 网络编程之UDP编程
网络编程之UDP编程 UDP协议是一种不可靠的网络协议,它在通信的2端各建立一个Socket,但是这个Socket之间并没有虚拟链路,这2个Socket只是发送和接受数据的对象,Java提供了Data ...
- 网络编程之TCP编程
网络编程之TCP编程 前面已经介绍过关于TCP协议的东西,这里不做赘述.Java对于基于TCP协议的网络通信提供了良好的封装,Java使用socket对象来代表两端的通信窗口,并通过Socket产生I ...
- 网络编程之Socket & ServerSocket
网络编程之Socket & ServerSocket Socket:网络套接字,网络插座,建立网络通信连接至少要一对端口号(socket).socket本质是编程接口(API),对TCP/IP ...
随机推荐
- [国嵌笔记][019][Eclipse集成开发环境]
Eclipse集成开发环境的作用 可以编译程序,也可以对程序进行在线调试 集成开发环境 1.JLink连接开发板的JTAG 2.JLink连接PC的USB 3.eclipse软件 4.gdb serv ...
- 什么是WEBserver? 经常使用的WEBserver有哪些?
地址:http://www.mamicode.com/ 什么是WEBserver? 经常使用的WEBserver有哪些? 一.什么是WEBserver Webserver能够解析HTTP协议.当Web ...
- js立体旋转展示效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 与改写url取文件的方法:NetworkRequest和DataAccessSerivice 文件
与改写url取文件的方法:NetworkRequest和DataAccessSerivice 文件 CMDNMapDataCache.cpp 读取二进制代码的方法
- 分布式CAP原理
根据维基百科定义[CAP] 根据定理,一个分布式系统最多只能满足其中两项, 不可能同时满则C-A-P三项 首先说一下对各项原则的理解 (1)一致性C: 单机环境下, 数据只有一份,所有的客户端访问的是 ...
- PHP获取中英文字符串的首字母
使用场景:在对地区进行筛选时,我们经常会看到按照英文字母进行筛选定位,起初想着是数据表里存储上地区与首字母关联关系,但是觉得太麻烦,然后就想着根据地区名称来获取首字母,然后对地区进行分组,由此便用到了 ...
- Linuxc - 通过管道,让小程序更有活力
通过管道,让小程序更有活力 root@jiqing:~/cspace/les6# ls avg.c avg.out input.c input.out 一个负责输入,一个负责统计平均值 avg.c # ...
- 查看 Apache并发请求数及其TCP连接状态【转】
查看 Apache并发请求数及其TCP连接状态 (2011-06-27 15:08:36) 服务器上的一些统计数据: 1)统计80端口连接数netstat -nat|grep -i "80& ...
- char (*p)[]和char *p[]的区别
理解的关键在于: 1. []的优先级高于*,(*p)[]理解为指向一个数组,*(p[])存放指针的数组 2. char (*p)[SIZE]:指向一维数组的指针,一维数组只能有SIZE个元素 char ...
- 苹果系统css样式变化
原因:苹果自带样式覆盖了 参考文章比较详细,就不自己写了,copy了一份~~~ @参考文章 只要在样式里面加一句去掉css去掉iPhone.iPad的默认按钮样式就可以了!~ input[type=& ...