一 为什么TCP协议比UDP协议传输数据可靠:
我们知道在传输数据的时候,数据是先存在操作系统的缓存中,然后发送给客户端,在客户端也是要经过客户端的操作系统的,因为这个过程涉及到计算机硬件,也就是物理层的一些东西,那么tcp协议在确认客户端接收到完整的信息之后才会删除服务端操作系统中的缓存,否则就会继续发,这才是TCP协议的可靠性根本原因,而UDP只管发送数据而不管客户端有没有收到,所以就会造成丢包现象。
二 基于套节子的编程:
基于TCP协议的套接字(无并发):
服务端:
import socket sever=socket.socket(socket.AF_INET,socket.) sever.blind(ip) sever.listen(5) sever.accept()#这个时候客户端没有发消息,服务端就会停在这 while True: conn,client_addr=sever.accept() print(client_addr) while True: try: data=conn.recv(1024) ##if not data:break##linux系统上使用 conn.send(data.upper()) except ConnectionResetError break conn.close() sever.close()
客户端:
import socket
client=socket.socket(socket.AF_INET,socket.SOCK.STREAM)
client.connect(ip)
while True:
msg=input('input:').strip()
if not msg:continue
client.send(msg.encode('utf-8'))
data=client.recv(1024)
这种情况下并没有并发效果,可以通过几个客户端连接到同一个服务端,所有的请求首先送到服务端半连接池,服务端再到伴了连接池取,
取出之后开始为第一个客户端服务,只要客户端不结束,那么就一直为客户端服务,不能为其他的客户端服务,其他的可以建成连接,但是没办法交互,
访问数量超过伴连接池规定,就会报错,伴连接池。
解决访问数量超过伴连接池报错问题:
import socket client=socket.socket(socket.AF_INET,socket.SOCK.STREAM) client.connect(ip) while True: msg=input('input:').strip() if not msg:continue client.send(msg.encode('utf-8')) data=client.recv(1024) 解决进不去半连接池问题:也就是没办法发请求,一个连接,五个等待。 在第一个人没有结束的时候,那么伴连接池的人都进不去, while True: try: client=socket.socket() client.connect((ip)) break except ExceptionError time.sleep(3) print('等待3秒')
三 基于UDP协议的套接字:
TCP:流逝协议 UDP:数据报协议 服务端: import socket sever=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) sever.bind((ip)) while True: client_data,client_addr=sever.recvfrom(1024) sever.sendto(client_data.upper(),client_addr) print(res) 客户端: import socket client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) while True: msg=input(':') client.sendto((ip)) sever_data,sever_addr=client.recvfrom(1024) print(sever_data,sever_addr) UDP:可以在不开启服务端的情况下,发消息,调用的为SOCK_DGRAM。
1 UDP的特征:
数据报协议,自带报头,完整的数据报,所以UDP没有粘包现象,发与收一一对应,这一点与TCP是不一样的,
UDP来发消息,稳定可靠的数据量就是512kb,所以我们定义一个1024就够了。超过这个数就会容易造成丢包的现象,所以UDP一般用于数据量比较小的场景,比如我们平时聊天信息等。
四 并发编程:
理论知识
并发指的是服务端,需要同时处理多个进程。
进程:正在执行的过程或者正在执行的程序。
程序:说白了就是一堆文件。
运行一个程序就是起了一个进程,进程是一个抽象的概念进程的概念。
二 进程与程序的区别
程序仅仅只是一堆代码而已,而进程指的是程序的运行过程。
举例:
比如我们要做饭,那么我们首先要有食材,食谱,同样还要有厨师。
在这个比喻中:
做蛋糕的食谱就是程序(即用适当形式描述的算法)
计算机科学家就是处理器(cpu)
而做饭各种原料就是输入数据。
进程就是厨师阅读食谱、取来各种原料以及烘制蛋糕等一系列动作的总和。
需要强调的是:同一个程序执行两次,那也是两个进程,比如打开暴风影音,虽然都是同一个软件,但是一个可以播放苍老师,一个可以播放波老师。
进程起源于操作系统,
2 操作系统:用于协调,管理,控制计算机硬件与软件的资源的一种控制程序
作用1:把复杂丑陋的硬件操作都封装成美丽的借口,提供给应用程序,
作用2:把进程(应用程序)对硬件的竞争变得有序,
3 计算机发展史:
1 第一个阶段:真空管和穿孔卡片
特点:
没有操作系统的概念
所有的程序设计都是直接操控硬件
工作过程:
程序员在墙上的机时表预约一段时间,然后程序员拿着他的插件版到机房里,将自己的插件板街道计算机里,这几个小时内他独享整个计算机资源,后面的一批人都得等着(两万多个真空管经常会有被烧坏的情况出现)。
后来出现了穿孔卡片,可以将程序写在卡片上,然后读入机而不用插件板
优点:
程序员在申请的时间段内独享整个资源,可以即时地调试自己的程序(有bug可以立刻处理)
缺点:
浪费计算机资源,一个时间段内只有一个人用。
注意:同一时刻只有一个程序在内存中,被cpu调用执行,比方说10个程序的执行,是串行的
2 第二阶段:晶体管和批处理系统
第二代计算机的产生背景: 由于当时的计算机非常昂贵,自认很自然的想办法较少机时的浪费。通常采用的方法就是批处理系统。 特点: 设计人员、生产人员、操作人员、程序人员和维护人员直接有了明确的分工,计算机被锁在专用空调房间中,由专业操作人员运行,这便是‘大型机’。 有了操作系统的概念 有了程序设计语言:FORTRAN语言或汇编语言,写到纸上,然后穿孔打成卡片,再讲卡片盒带到输入室,交给操作员,然后喝着咖啡等待输出接口 第二代如何解决第一代的问题/缺点: 1.把一堆人的输入攒成一大波输入, 2.然后顺序计算(这是有问题的,但是第二代计算也没有解决) 3.把一堆人的输出攒成一大波输出 现代操作系统的前身:(见图) 优点:批处理,节省了机时 缺点: 1.整个流程需要人参与控制,将磁带搬来搬去(中间俩小人) 2.计算的过程仍然是顺序计算-》串行 3.程序员原来独享一段时间的计算机,现在必须被统一规划到一批作业中,等待结果和重新调试的过程都需要等同批次的其他程序都运作完才可以(这极大的影响了程序的开发效率,无法及时调试程序)
3第三阶段:集成电路芯片和多道程序设计
第三代计算机基本上解决了前两代计算机的一些缺点,比如串行等问题。
第三代计算机的操作系统广泛应用了第二代计算机的操作系统没有的关键技术:多道技术
cpu在执行一个任务的过程中,若需要操作硬盘,则发送操作硬盘的指令,指令一旦发出,硬盘上的机械手臂滑动读取数据到内存中,这一段时间,cpu需要等待,
时间可能很短,但对于cpu来说已经很长很长,长到可以让cpu做很多其他的任务,如果我们让cpu在这段时间内切换到去做其他的任务,这样cpu不就充分利用了吗。
这正是多道技术产生的技术背景
五 多道技术:
是想要在单个cpu的情况下,实现多个进程并发执行的效果。
多道技术:空间上的复用(多道程序重用一个内存空间)
时间上的复用:(多道程序复用CPU时间)
1 时间上的复用的问题:1 CPU遇到io操作要切换(提升效率)
2 一个进程占用CPU时间过长也要切,操作系统来切换(降低效率)
1.时间上的复用 当一个资源在时间上复用时,不同的程序或用户轮流使用它,第一个程序获取该资源使用结束后,在轮到第二个。。。第三个。。。 例如:只有一个cpu,多个程序需要在该cpu上运行,操作系统先把cpu分给第一个程序,在这个程序运行的足够长的时间(时间长短由操作系统的算法说了算)
或者遇到了I/O阻塞,操作系统则把cpu分配给下一个程序,以此类推,直到第一个程序重新被分配到了cpu然后再次运行,由于cpu的切换速度很快,
给用户的感觉就是这些程序是同时运行的,或者说是并发的,或者说是伪并行的。至于资源如何实现时间复用,或者说谁应该是下一个要运行的程序,
以及一个任务需要运行多长时间,这些都是操作系统的工作。 2.空间上的复用 每个客户都获取了一个大的资源中的一小部分资源,从而减少了排队等待资源的时间。 例如:多个运行的程序同时进入内存,硬件层面提供保护机制来确保各自的内存是分割开的,且由操作系统控制,这比一个程序独占内存一个一个排队进入内存效率要高的多。 有关空间复用的其他资源还有磁盘,在许多系统中,一个磁盘同时为许多用户保存文件。分配磁盘空间并且记录谁正在使用哪个磁盘块是操作系统资源管理的典型任务。 这两种方式合起来便是多道技术
2 空间复用问题:
但是有一个很关键的问题就是,多个进程共享内存空间,但是多个进程之间的内存空间必须是互相隔离的,否则会造成一系列问题:
程序之间的内存必须分割,这种分割需要在硬件层面实现,由操作系统控制。如果内存彼此不分割,则一个程序可以访问另外一个程序的内存,
首先丧失的是安全性,比如你的qq程序可以访问操作系统的内存,这意味着你的qq可以拿到操作系统的所有权限。
其次丧失的是稳定性,某个程序崩溃时有可能把别的程序的内存也给回收了,比方说把操作系统的内存给回收了,则操作系统崩溃。
3 分时操作系统:
多个联机终端+多道技术
其实第三代计算机采用的依然是批量处理模式,那么为了昂所有的用户觉得自己在独享服务器啊恩么做呢:一个计算机,一个cpu,每个客户端都可以连接到服务端,然后每个客户端在服务端都有一个进程,那么客户端的电脑想要运行程序首先把程序传输到服务端,然后服务端把运行结果返给客户端。这个时候就用到了多道技术,在多个进程之间切换。
把20个客户端同时加载到服务端的内存,那么这20个客户端一般不会同时运行,一部分在进行IO,一部分在进行,就绪状态,
那么CPU就可以采用多道的方式来处里个别的正在运行的程序,20个客户端同时加载到内存,有17在思考,3个在运行,cpu就采用多道的方式处理内存中的这3个程序,
由于客户提交的一般都是简短的指令而且很少有耗时长的,索引计算机能够为许多用户提供快速的交互式服务,所有的用户都以为自己独享了计算机资源。