异常处理
一、远程执行命令
#Struct模块使用 import struct res=struct.pack('i',1333123129) print(res,len(res)) recv_header=struct.unpack('i',res) print(recv_header[0]) #服务端 import socket import subprocess import struct server=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 流式协议=》tcp # print(server) server.bind(('127.0.0.1',8080)) server.listen(5) # 链接循环 while True: conn,addr=server.accept() print(addr) # 通信循环 while True: try: cmd=conn.recv(1024) if len(cmd) == 0:break # 针对linux obj=subprocess.Popen(cmd.decode('utf-8'),shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) stdout_res=obj.stdout.read() stderr_res=obj.stderr.read() total_size=len(stdout_res) + len(stderr_res) print(total_size) # 1、先发送数据的总大小 conn.send(struct.pack('i',total_size)) # 2、再发送真实的数据 conn.send(stdout_res) conn.send(stderr_res) except Exception: # 针对windows break conn.close() server.close() #客户端 import socket import struct client=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 流式协议=》tcp client.connect(('127.0.0.1',8080)) while True: cmd=input(">>>: ").strip() if len(cmd) == 0:continue client.send(cmd.encode('utf-8')) # 1、先拿到数据的总大小 header_bytes=client.recv(4) header=struct.unpack('i',header_bytes) total_size=header[0] # 2、再接收数据 recv_size=0 res=b'' while recv_size < total_size: data=client.recv(1024) recv_size+=len(data) res+=data print(res.decode('gbk'))
二、解决钻包问题
#struct模块的使用 import struct import json header_dic={ 'filenme':"a.txt", 'md5':"sdfasfdasfdasfd123123213", "total_size":12311111111111231232132132131231231231231231231231231231231111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 } header_json=json.dumps(header_dic) header_json_bytes=header_json.encode('utf-8') # print(header_json_bytes) # print(len(header_json_bytes)) #服务端 import socket import subprocess import struct import json server=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 流式协议=》tcp # print(server) server.bind(('127.0.0.1',8080)) server.listen(5) # 链接循环 while True: conn,addr=server.accept() print(addr) # 通信循环 while True: try: cmd=conn.recv(1024) if len(cmd) == 0:break # 针对linux obj=subprocess.Popen(cmd.decode('utf-8'),shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) stdout_res=obj.stdout.read() stderr_res=obj.stderr.read() total_size=len(stdout_res) + len(stderr_res) print(total_size) header_dic = { 'filenme': "a.txt", 'md5': "sdfasfdasfdasfd123123213", "total_size": total_size } header_json = json.dumps(header_dic) header_json_bytes = header_json.encode('utf-8') # 1、先发送报头的长度 conn.send(struct.pack('i',len(header_json_bytes))) # 2、再发送报头 conn.send(header_json_bytes) # 3、然后发送真实的数据 conn.send(stdout_res) conn.send(stderr_res) except Exception: # 针对windows break conn.close() server.close() #客户端 import socket import struct import json client=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 流式协议=》tcp client.connect(('127.0.0.1',8080)) while True: cmd=input(">>>: ").strip() if len(cmd) == 0:continue client.send(cmd.encode('utf-8')) # 1、先拿到报头的长度 header_json_bytes_size=struct.unpack('i',client.recv(4))[0] # 2、再收报头 header_json_bytes=client.recv(header_json_bytes_size) header_json=header_json_bytes.decode('utf-8') header_dic=json.loads(header_json) print(header_dic) # 3、最后接收数据 total_size=header_dic['total_size'] recv_size=0 res=b'' while recv_size < total_size: data=client.recv(1024) recv_size+=len(data) res+=data print(res.decode('gbk'))
三、基于udp协议的套接字通信
#服务端 # import socket from socket import * import time server=socket(AF_INET,SOCK_DGRAM) server.bind(('127.0.0.1',8080)) while True: data,client_addr=server.recvfrom(1024) time.sleep(10) server.sendto(data.upper(),client_addr) #客户端 # import socket from socket import * client = socket(AF_INET, SOCK_DGRAM) while True: msg=input('>>>: ').strip() client.sendto(msg.encode('utf-8'),('127.0.0.1',8080)) data,server_addr=client.recvfrom(1024) print(data.decode('utf-8'))
四、socketserver模块
4.1tcp协议
#服务端 import socketserver class MyrequestHandler(socketserver.BaseRequestHandler): def handle(self): # self.request # conn对象 print(self.client_address) while True: try: data=self.request.recv(1024) if len(data) == 0:break self.request.send(data.upper()) except Exception: break self.request.close() if __name__ == '__main__': s=socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyrequestHandler) s.serve_forever() #客户端 import socket import struct client=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 流式协议=》tcp client.connect(('127.0.0.1',8080)) while True: cmd=input(">>>: ").strip() if len(cmd) == 0:continue client.send(cmd.encode('utf-8')) data=client.recv(1024) print(data.decode('utf-8'))
4.2udp协议
#服务端 import socketserver import time class MyrequestHandler(socketserver.BaseRequestHandler): def handle(self): # self.request # conn对象 data=self.request[0] self.request[1].sendto(data.upper(),self.client_address) time.sleep(10) if __name__ == '__main__': s=socketserver.ThreadingUDPServer(('127.0.0.1',8080),MyrequestHandler) s.serve_forever() #客户端 # import socket from socket import * client = socket(AF_INET, SOCK_DGRAM) while True: msg=input('>>>: ').strip() client.sendto(msg.encode('utf-8'),('127.0.0.1',8080)) data,server_addr=client.recvfrom(1024) print(data.decode('utf-8'))
五、异常处理
5.1、什么是异常
异常是错误发生的信号,程序中一旦出现错误,python就会产生一个异常
一旦该异常没有被处理,该异常就会抛出来,程序的运行也随即终止
5.2、为何要处理异常
为了增强程序的容错性、鲁棒性、健壮性
5.3、异常的三个组成部分
异常的追踪信息
异常的类型
异常的内容
5.4、错误=》异常
5.4.1 语法错误:SyntaxError
应该在程序运行前就改正
5.4.2 逻辑错误
age=input(">>: ").strip()
if age.isdigit():
age=int(age)
print(age > 10)
5.5异常处理语法
try:
代码1
代码2
代码3
except 异常类型1 as e:
处理异常的代码1
except 异常类型2 as e:
处理异常的代码2
except (异常类型3,异常类型4,异常类型5) as e:
处理异常的代码3
except Exception as e:
处理异常的代码4
else:
被监测的代码块没有发生异常时执行的代码
finally:
无论被监测的代码块有无异常都会执行该代码
print('===>other code<====')
#try不能单独和else连用,如果要用else,必须配合except #例如: try: print(111) print(222) print(3333) except Exception: pass else: print('ok') print('===>other code<====') # try: print('start...') l=[] l[100] print('end...') except KeyError as e: print("Key错误:",e) except IndexError as e: print("索引错误:",e) except Exception: pass print('===>other code<====') # try: 执行sql1 执行sql2 执行sql3 执行sql4 执行sql5 except Exception: 执行回滚操作 else: 执行提交操作 print('===>other code<====') try: print(1111) sadf print(2222) print(33333) finally: print('====>finally') # 回收资源 上半部分 print(111) print(222) print(333) names=['egon','jack',] # if len(names) != 3: # raise Exception("数据错误") assert len(names) == 3 # 下半部分 print(names[2]) class NameType(BaseException): def __init__(self,msg): self.msg=msg def __str__(self): return "<%s>" %self.msg class People: def __init__(self,name): self.__name=name @property def name(self): return self.__name @name.setter def name(self,v): if not isinstance(v,str): raise NameType("名字必须是str类型") self.__name=v @name.deleter def name(self): del self.__name obj=People('egon') obj.name=123123 class Animal: def speak(self): raise Exception("必须定义speak方法") def run(self): raise Exception("必须定义run方法") class Dog(Animal): pass class People(Animal): pass obj1=Dog() obj2=People() obj1.speak() # obj1.run()
六、开启子进程
from multiprocessing import Process import time def task(n): print('starting...',x) time.sleep(n) print('end...') x = 100 if __name__ == '__main__': p=Process(target=task,args=(3,)) p.start() # 发生系统调用,让操作系统启动进程 print('主。。。。',x)
from multiprocessing import Process import time x = 100 class Myprocess(Process): def __init__(self,n): self.n = n super().__init__() def run(self) -> None: print('starting...', x) time.sleep(self.n) print('end...') if __name__ == '__main__': p=Myprocess(3) p.start() print("主。。。")
七、进程空间彼此隔离
from multiprocessing import Process import time x = 100 def task(n): global x print('starting...') time.sleep(n) x=0 print('end...') if __name__ == '__main__': p=Process(target=task,args=(3,)) p.start() # 发生系统调用,让操作系统启动进程 time.sleep(10) print('主。。。。',x)
八、Join方法
from multiprocessing import Process import time import os def task(n): print(os.getpid(),os.getppid()) print('进程 %s starting...' %n) time.sleep(n) print('进程 %s end...' %n) if __name__ == '__main__': p1=Process(target=task,args=(1,)) p2=Process(target=task,args=(2,)) p3=Process(target=task,args=(3,)) # p1.start() # 发生系统调用,让操作系统启动进程 # p2.start() # 发生系统调用,让操作系统启动进程 p3.start() # 发生系统调用,让操作系统启动进程 start=time.time() # time.sleep(10) p3.join() p1.join() p2.join() print(time.time() - start) p3.terminate() print(p3.is_alive()) print(p3.name) print(p3.pid) p3.join(1) print('主。。。。',os.getpid())
九、操作系统发展史
多道技术
空间上的复用:将内存分为几部分,每个部分放入一个程序,这样,同一时间内存中就有了多道程序。
时间上的复用:当一个程序在等待I/O时,另一个程序可以使用cpu,如果内存中可以同时存放足够多的作业,则cpu的利用率可以接近100%,类似于我们小学数学所学的统筹方法。(操作系统采用了多道技术后,可以控制进程的切换,或者说进程之间去争抢cpu的执行权限。这种切换不仅会在一个进程遇到io时进行,一个进程占用cpu时间过长也会切换,或者说被操作系统夺走cpu的执行权限)
空间上的复用:将内存分为几部分,每个部分放入一个程序,这样,同一时间内存中就有了多道程序。
时间上的复用:当一个程序在等待I/O时,另一个程序可以使用cpu,如果内存中可以同时存放足够多的作业,则cpu的利用率可以接近100%,类似于我们小学数学所学的统筹方法。(操作系统采用了多道技术后,可以控制进程的切换,或者说进程之间去争抢cpu的执行权限。这种切换不仅会在一个进程遇到io时进行,一个进程占用cpu时间过长也会切换,或者说被操作系统夺走cpu的执行权限)
程序
一堆代码文件
一堆代码文件
进程
一个正在运行的程序or程序的运行过程
一个正在运行的程序or程序的运行过程
并发:
多个进程/任务看起来是同时运行的
多个进程/任务看起来是同时运行的
并行:
多个进程/任务是真正意义上的同时运行
多个进程/任务是真正意义上的同时运行
进程的三种运行状态
运行态
就绪态
阻塞态
运行态
就绪态
阻塞态
任务的提交方式
同步
异步
同步
异步