网络知识,多线程,socketserver
一.网络知识
1.DHCP, 自动为局域网内容电脑分配ip.
2.网关, 路由器中连接交换机的口.
3.ip , 规定网络地址的协议叫ip地址,广泛采用V4版本即ipv4,它规定网络地址由32位二进制表示
4.子网掩码 , 就是表示子网络特征的一个参数。它在形式上等同于IP地址,也是一个32位二进制数字,它的网络部分全部为1,主机部分全部为0。比如,IP地址172.16.10.1,如果已知网络部分是前24位,主机部分是后8位,那么子网络掩码就是11111111.11111111.11111111.00000000,写成十进制就是255.255.255.0。
将挡住的ip位数作为网段 , 为党住的部分作为可变的值.
5.局域网 城域网 广域网
广播 单播 广播风暴
6.arp协议,就是讲IP地址解析成mac地址。
7.DNS
网络连接: 域名解析
www.luffycity.com 47.95.64.113
www.oldboyedu.com 101.200.195.98
连接
sk = socket.socket()
sk.connect(('47.95.64.113',80))
域名和IP的对应关系在哪里?
hosts文件
二.多线程
1.线程:顾名思义,就是一条流水线工作的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程
2.进程: 只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位。
3.多线程(即多个控制线程)的概念是,在一个进程中存在多个控制线程,多个控制线程共享该进程的地址空间,相当于一个车间内有多条流水线,都共用一个车间的资源。(一个进程里面开多个线程(共享同一个进程里面的内存空间))
注意:
a.所以进程里面真正干活的是线程(进程里面有线程)
b.进程只是用来把资源互相隔离开,而线程才是真正负责cpu来调动他的
4.进程与线程的区别:
a.创建线程比进程开销小(开一个进程,里面就有空间了,而线程在进程里面,就没必要在开一个空间了)
b.多线程一定是在一个进程里面开启的,共享进程里面的资源
c.线程启动的速度快
d.同一进程下的多个线程共享进程的资源,而多个进程之间内存空间是隔离的
e.线程可以跟它所在的进程之内 的线程通信
5.为什么使用多线程
1. 多线程共享一个进程的地址空间
2. 线程比进程更轻量级,线程比进程更容易创建可撤销,在许多操作系统中,创建一个线程比创建一个进程要快10-100倍,在有大量线程需要动态和快速修改时,这一特性很有用
3. 若多个线程都是cpu密集型的,那么并不能获得性能上的增强,但是如果存在大量的计算和大量的I/O处理,拥有多个线程允许这些活动彼此重叠运行,从而会加快程序执行的速度。
4. 在多cpu系统中,为了最大限度的利用多核,可以开启多个线程,比开进程开销要小的多。(这一条并不适用于python)
import time import threading def task(n): print('开始执行任务:',n) time.sleep(10) print('...') print('任务%s 执行完毕:'%n) while True: name = input("请输入任务:") t = threading.Thread(target=task,args=(name,)) t.start()
import time import socket import threading def task(conn): time.sleep(20) data = conn.recv(1024) print(data) conn.close() server = socket.socket() server.bind(('192.168.13.84',8001,)) server.listen(5) while True: conn,addr = server.accept() t = threading.Thread(target=task,args=(conn,)) t.start()
三.socketserver源码
SocketServer内部使用 IO多路复用 以及 “多线程” 和 “多进程” ,从而实现并发处理多个客户端请求的Socket服务端。即:每个客户端请求连接到服务器时,Socket服务端都会在服务器是创建一个“线程”或者“进程” 专门负责处理当前客户端的所有请求。
1.ThreadingTCPServer
使用ThreadingTCPServer:
创建一个继承自 SocketServer.BaseRequestHandler 的类
类中必须定义一个名称为 handle 的方法
启动ThreadingTCPServer
import socketserver class MyServer(socketserver.BaseRequestHandler): def handle(self): self.request self.client_address self.server # 编写代码 server = socketserver.ThreadingTCPServer(('192.168.13.84',8001,),MyServer) """ server.server_address = server_address server.RequestHandlerClass = RequestHandlerClass server.__is_shut_down = threading.Event() server.__shutdown_request = False server.socket = socket.... - socket.bind - socket.listen """ server.serve_forever()
ThreadingTCPServer的类图关系
内部调用流程为:
- 启动服务端程序
- 执行 TCPServer.__init__ 方法,创建服务端Socket对象并绑定 IP 和 端口
- 执行 BaseServer.__init__ 方法,将自定义的继承自SocketServer.BaseRequestHandler 的类 MyRequestHandle赋值给self.RequestHandlerClass
- 执行 BaseServer.server_forever 方法,While 循环一直监听是否有客户端请求到达 ...
- 当客户端连接到达服务器
- 执行 ThreadingMixIn.process_request 方法,创建一个 “线程” 用来处理请求
- 执行 ThreadingMixIn.process_request_thread 方法
- 执行 BaseServer.finish_request 方法,执行 self.RequestHandlerClass() 即:执行 自定义 MyRequestHandler 的构造方法(自动调用基类BaseRequestHandler的构造方法,在该构造方法中又会调用 MyRequestHandler的handle方法)