| |
| ''' |
| socket, urllib,urllib3 , requests, grab, pycurl |
| ''' |
| |
| ''' |
| 应用层:HTTP,FTP,NFS |
| |
| 表示层:Telnet,SNMP |
| |
| 会话层:SMTP,DNS |
| |
| 传输层:TCP,UDP |
| |
| 网络层:IP,ICMP,ARP, |
| |
| 数据链路层:Ethernet,PPP,PDN,SLIP,FDDI |
| |
| 物理层:IEEE 802.1A,IEEE 802.11 |
| ''' |
| |
| ''' |
| 软件系统体系结构: |
| C/S体系结构: |
| 指的是客户端/服务端 例如;QQ |
| |
| B(browser)/S体系结构: |
| 指的是浏览器/服务端 例如12306(网站);购物网站 |
| |
| 两者区别: |
| C/S :优点:交互性好,对服务器压力小,安全 ;缺点:服务器更新时需要同步更新客户端 |
| B/S:优点:不需要更新客户端 缺点:交互性差,安全性低 |
| ''' |
三次握手过程:
| 1首先客户端向服务端发送一个带有SYN 标志,以及随机生成的序号100(0字节)的报文 |
| 2服务端收到报文后返回一个报文(SYN200(0字节),ACk1001(字节+1))给客户端 |
| 3客户端再次发送带有ACk标志201(字节+)序号的报文给服务端 |
| 至此三次握手过程结束,客户端开始向服务端发送数据。 |
| 1客户端向服务端发起请求:我想给你通信,你准备好了么? |
| 2服务端收到请求后回应客户端:I'ok,你准备好了么 |
| 3客户端礼貌的再次回一下客户端:准备就绪,咱们开始通信吧! |
| 整个过程跟打电话的过程一模一样:1喂,你在吗2在,我说的你听得到不3恩,听得到(接下来请 |
| 开始你的表演) |
| 补充:SYN:请求询问,ACk:回复,回应。 |
四次挥手过程:
| 由于TCP连接是可以双向通信的(全双工),因此每个方向都必须单独进行关闭(这句话才是 |
| 精辟,后面四个挥手过程都是其具体实现的语言描述) |
| 四次挥手过程,客户端和服务端都可以先开始断开连接 |
| 1客户端发送带有fin标识的报文给服务端,请求通信关闭 |
| 2服务端收到信息后,回复ACK答应关闭客户端通信(连接)请求 |
| 3服务端发送带有fin标识的报文给客户端,也请求关闭通信 |
| 4客户端回应ack给服务端,答应关闭服务端的通信(连接)请求 |
| |
| ''' |
| ARP协议,全称“Address Resolution Protocol”,中文名是地址解析协议,使用ARP协议可实现通过IP地址获得对应主机的物理地址(MAC地址)。 |
| ''' |
| |
| |
| ''' |
| 1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接 |
| 2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付 |
| 3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的 |
| UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等) |
| 4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信 |
| 5、TCP首部开销20字节;UDP的首部开销小,只有8个字节 |
| 6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道 |
| ''' |
| |
| |
| ''' |
| tcp:可靠 对方给了确认收到信息,才发下一个,如果没收到确认信息就重发 |
| udp:不可靠 一直发数据,不需要对方回应 |
| ''' |
| |
| ''' |
| 两者范围不一样: |
| 局域网就是在固定的一个地理区域内由2台以上的电脑用网线和其他网络设备搭建而成的一个封闭的计算机组,范围在几千米以内; |
| 广域网是一种地域跨度非常大的网络集合,范围在几十公里到几千公里。 |
| |
| 两者的IP地址设置不一样: |
| 局域网里面,必须在网络上有一个唯一的IP地址,这个IP地址是唯一的,在另外一个局域网,这个IP地址仍然能够使用。 |
| 广域网上的每一台电脑(或其他网络设备)都有一个或多个广域网IP地址,而且不能重复。 |
| ''' |
| |
| ''' |
| Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部。 |
| |
| 服务端: |
| 创建socket对象,绑定ip端口bind(), 设置最大链接数listen(), accept()与客户端的connect()创建双向管道, send(), recv(),close() |
| |
| 客户端: |
| 创建socket对象,connect()与服务端accept()创建双向管道, send(),recv(),close() |
| ''' |
| |
| ''' |
| 粘包: |
| 数据粘在一起,主要因为:接收方不知道消息之间的界限,不知道一次性提取多少字节的数据造成的数据量比较小,时间间隔比较短,就合并成了一个包,这是底层的一个优化算法(Nagle算法) |
| ''' |
| |
| ''' |
| I/O多路复用是用于提升效率,单个进程可以同时监听多个网络连接IO。 |
| |
| 举例: |
| 通过一种机制,可以监视多个文件描述符,一旦描述符就绪(读就绪和写就绪),能通知程序进行相应的读写操作,I/O多路复用避免阻塞在io上,原本为多进程或多线程来接收多个连接的消息变为单进程或单线程保存多个socket的状态后轮询处理。 |
| ''' |
| |
| ''' |
| 在互联网上防火墙是一种非常有效的网络安全模型,通过它可以隔离风险区域(即Internet或有一定风险的网络)与安全区域(局域网)的连接,同时不会妨碍人们对风险区域的访问。所以它一般连接在核心交换机与外网之间。 |
| |
| 1.过滤进出网络的数据 |
| 2.2.管理进出访问网络的行为 |
| 3.3.封堵某些禁止业务 |
| 4.4.记录通过防火墙信息内容和活动 |
| 5.5.对网络攻击检测和告警 |
| |
| ''' |
| |
| ''' |
| I/O多路复用的本质就是用select/poll/epoll,去监听多个socket对象,如果其中的socket对象有变化,只要有变化,用户进程就知道了。 |
| |
| select是不断轮询去监听的socket,socket个数有限制,一般为1024个; |
| |
| poll还是采用轮询方式监听,只不过没有个数限制; |
| |
| epoll并不是采用轮询方式去监听了,而是当socket有变化时通过回调的方式主动告知用户进程。 |
| |
| ''' |
| |
| ''' |
| 1.进程是操作系统资源分配的最小单位,拥有独立的资源和地址空间 |
| 2.线程是CPU调度的单位 |
| 3.统一进程中的线程是资源共享的。 |
| 4.协程是用户级别的,程序之间的切换由用户自行处理,节省了CPU的调度时间。 |
| ''' |
| |
| ''' |
| 全局解释锁,每次只能一个线程获得cpu的使用权:为了线程安全,也就是为了解决多线程之间的数据完整性和状态同步而加的锁,因为我们知道线程之间的数据是共享的。 |
| ''' |
| |
| |
| import threadpool, time |
| |
| with open(r'../uoko_house_id.txt', 'r', encoding='utf-8') as f: |
| roomIdLi = f.readlines() |
| roomIdList =[x.replace('\n','').replace(' ','') for x in roomIdLi] |
| print(roomIdList) |
| li = [[i, item] for i, item in enumerate(roomIdList)] |
| |
| def run(roomId): |
| """对传入参数进行处理""" |
| print('传入参数为:', roomId) |
| time.sleep(1) |
| |
| def main(): |
| roomList = li |
| start_time = time.time() |
| print('启动时间为:', start_time) |
| pool = threadpool.ThreadPool(10) |
| requests = threadpool.makeRequests(run, roomList) |
| [pool.putRequest(req) for req in requests] |
| pool.wait() |
| print("共用时:", time.time()-start_time) |
| |
| if __name__ == '__main__': |
| main() |
| |
| |
| from multiprocessing.pool import Pool |
| from time import sleep |
| |
| def fun(a): |
| sleep(5) |
| print(a) |
| |
| if __name__ == '__main__': |
| p = Pool() |
| for i in range(10): |
| p.apply_async(fun, args= (i, )) |
| p.close() |
| p.join() |
| print("end") |
| |
| 为每个线程创建一个独立的空间,使得线程对自己的空间中的数据进行操作(数据隔离)。 |
| import threading |
| from threading import local |
| import time |
| |
| obj = local() |
| |
| def task(i): |
| obj.xxxxx = i |
| time.sleep(2) |
| print(obj.xxxxx,i) |
| |
| for i in range(10): |
| t = threading.Thread(target=task,args=(i,)) |
| t.start() |
| |
| python提供了多种进程通信的方式,主要Queue和Pipe这两种方式,Queue用于多个进程间实现通信,Pipe是两个进程的通信。 |
| |
| |
| from multiprocessing import Process, Queue |
| import os,time,random |
| |
| |
| def proc_write(q,urls): |
| print 'Process is write....' |
| for url in urls: |
| q.put(url) |
| print 'put %s to queue... ' %url |
| time.sleep(random.random()) |
| |
| |
| def proc_read(q): |
| print('Process is reading...') |
| while True: |
| url = q.get(True) |
| print('Get %s from queue' %url) |
| |
| if __name__ == '__main__': |
| |
| q = Queue() |
| proc_write1 = Process(target=proc_write,args=(q,['url_1','url_2','url_3'])) |
| proc_write2 = Process(target=proc_write,args=(q,['url_4','url_5','url_6'])) |
| proc_reader = Process(target=proc_read,args=(q,)) |
| |
| proc_write1.start() |
| proc_write2.start() |
| |
| proc_reader.start() |
| |
| proc_write1.join() |
| proc_write2.join() |
| |
| proc_reader.terminate() |
| |
| |
| import multiprocessing |
| import os,time,random |
| |
| |
| def proc_send(pipe,urls): |
| |
| for url in urls: |
| |
| print 'Process is send :%s' %url |
| pipe.send(url) |
| time.sleep(random.random()) |
| |
| |
| def proc_recv(pipe): |
| while True: |
| print('Process rev:%s' %pipe.recv()) |
| time.sleep(random.random()) |
| |
| if __name__ == '__main__': |
| |
| pipe = multiprocessing.Pipe() |
| p1 = multiprocessing.Process(target=proc_send,args=(pipe[0],['url_'+str(i) for i in range(10) ])) |
| p2 = multiprocessing.Process(target=proc_recv,args=(pipe[1],)) |
| |
| p1.start() |
| p2.start() |
| |
| p1.join() |
| p2.terminate() |
| |
| ''' |
| 同步:执行一个操作之后,需要主动等待返回结果; |
| 异步:执行一个操作之后,不需要主动等待返回结果,若接收到结果通知,再回来执行刚才没执行完的操作。 |
| 同步和异步关心的问题是:要不要主动等待结果。 |
| |
| 阻塞:在执行一个操作时,不能做其他操作; |
| 非阻塞:在执行一个操作时,能做其他操作。 |
| 阻塞和非阻塞关心的问题是:能不能做其他操作。 |
| ''' |
| |
| ''' |
| 1:交换机:是负责内网里面的数据传递(arp协议)根据MAC地址寻址。 |
| 路由器:在网络层,路由器根据路由表,寻找该ip的网段。 |
| 2:路由器可以把一个IP分配给很多个主机使用,这些主机对外只表现出一个IP。 |
| 交换机可以把很多主机连起来,这些主机对外各有各的IP。 |
| 3:交换机是做端口扩展的,也就是让局域网可以连进来更多的电脑。 |
| 路由器是用来做网络连接,也就是连接不同的网络。 |
| ''' |
| |
| ''' |
| 在互联网上,所有的地址都是ip地址,现阶段主要是IPv4(比如:110.110.110.110)。 |
| 但是这些ip地址太难记了,所以就出现了域名(比如http://baidu.com)。 |
| 域名解析就是将域名,转换为ip地址的这样一种行为。 |
| ''' |
| |
| ''' |
| Hosts是一个没有扩展名的系统文件,可以用记事本等工具打开,其作用就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”, |
| 当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从Hosts文件中寻找对应的IP地址, |
| 一旦找到,系统会立即打开对应网页,如果没有找到,则系统会再将网址提交给DNS域名解析服务器进行IP地址的解析。 |
| |
| 文件路径:C:\WINDOWS\system32\drivers\etc。 |
| 将127.0.0.1 www.163.com 添加在最下面 |
| 修改后用浏览器访问“www.163.com”会被解析到127.0.0.1,导致无法显示该网页。 |
| ''' |
| |
| ''' |
| 生产者与消费者模式是通过一个容器来解决生产者与消费者的强耦合关系,生产者与消费者之间不直接进行通讯, |
| 而是利用阻塞队列来进行通讯,生产者生成数据后直接丢给阻塞队列,消费者需要数据则从阻塞队列获取, |
| 实际应用中,生产者与消费者模式则主要解决生产者与消费者的生产与消费的速率不一致的问题,达到平衡生产者与消费者的处理能力,而阻塞队列则相当于缓冲区。 |
| |
| 应用场景:用户提交订单,订单进入引擎的阻塞队列中,由专门的线程从阻塞队列中获取数据并处理。 |
| |
| 优势: |
| 1;解耦 |
| 假设生产者和消费者分别是两个类。如果让生产者直接调用消费者的某个方法,那么生产者对于消费者就会产生依赖(也就是耦合)。 |
| 将来如果消费者的代码发生变化,可能会影响到生产者。而如果两者都依赖于某个缓冲区,两者之间不直接依赖,耦合也就相应降低了。 |
| 2:支持并发 |
| 生产者直接调用消费者的某个方法,还有另一个弊端。由于函数调用是同步的(或者叫阻塞的),在消费者的方法没有返回之前,生产者只能一直等着 |
| 而使用这个模型,生产者把制造出来的数据只需要放在缓冲区即可,不需要等待消费者来取。 |
| 3:支持忙闲不均 |
| 缓冲区还有另一个好处。如果制造数据的速度时快时慢,缓冲区的好处就体现出来了。 |
| 当数据制造快的时候,消费者来不及处理,未处理的数据可以暂时存在缓冲区中。等生产者的制造速度慢下来,消费者再慢慢处理掉。 |
| ''' |