网络编程日考
异常处理,socket
1什么是异常,异常的三个组成是什么?
异常是错误发生的信号,一旦程序出错就会产生一个异常,
如果该异常没有被处理,该异常就会被抛出来,程序的运行随即终止
1.具体哪一行代码抛出的异常
2.异常的种类
3.异常的内容信息
2如何正确处理异常
1.针对语法的错误,应该在程序运行前立即改正
2.针对逻辑错误:
2.1 如果逻辑错误发生的条件是可以预知的,应该if判断,预防异常
2.2如果逻辑错误发生的条件是不可预知的,那么异常一个会发生,
考虑到程序的健壮性,我们应该处理异常,做好补救措施
3异常处理的完整语法是?
try:
代码块
except 异常的类型 as e:
发生异常后要执行的代码
except 异常的类型 as e:
发生异常后要执行的代码
...
else:
没有异常,会运行此处代码
finally:
print('无论异常与否,都会执行该代码,通常是执行清理工作')
4raise的功能与用途
主动触发异常,用来制定规范
在不符合Python解释器的语法或逻辑规则时,是由Python解释器主动触发的各种类型
的异常,而对于违反程序员自定制的各类规则,则需要由程序员自己来明确地触发异
常,这就用到了raise语句,raise后必须是一个异常的类或者是异常的实例
5assert的功能与用途
语法:assert 判断条件,错误提示语句
条件成立,程序正常运行,不成立,抛出AssertionError:错误提示语句
用途:程序员测试bug
6什么是网络
物理连接介质+互联网通信协议
7osi七层是哪七层
应用层
表示层
会话层
传输层
网络层
数据链路层
物理层
osi协议
1.简述osi五层,每一层的协议与作用
应用层: 封装数据
http,ftp,自定义协议
传输层: 封装端口
tcp或者udp
网络层(包): 封装ip
IP协议
数据链路层(帧):定义了电信号的分组方式,封装mac地址
ethernet以太网协议
物理层(bit):负责发送电信号bit(会把数据链路层发过来的数据转换成电信号)
2,简述arp协议的工作步骤
协议工作方式:每台主机ip都是已知的
例如:主机172.16.10.10/24访问172.16.10.11/24
一:首先通过ip地址和子网掩码区分出自己所处的子网
二:分析172.16.10.10/24与172.16.10.11/24处于同一网络(如果不是同一网络,那么下表中目标ip为172.16.10.1,通过arp获取的是网关的mac
三:这个包会以广播的方式在发送端所处的自网内传输,所有主机接收后拆开包,发现目标ip为自己的,就响应,返回自己的mac
3,画出atm加购物车项目架构图
4,画选课系统项目架构图
tcp协议/udp协议
1画出tcp协议三次握手与四次挥手的状态图,注意:客户端与服务端的状态都要画
2解释为何tcp协议建链接需要三次握手,断链接却需要四次挥手
3解释基于tcp协议传输数据为何可靠,udp为何不可靠
4什么是半链接池
基于udp协议和tcp协议的支持并发的套接字通信
tcp
服务端
import socketserver
class MyRequestHandler(socketserver.BaseRequestHandler):
def handle(self): # 处理通信
print(self.client_address)
while True:
try:
data = self.request.recv(1024) # self.request=>conn
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, bind_and_activate=True)
s.serve_forever()
客户端
from socket import *
client=socket(AF_INET,SOCK_STREAM)
client.connect(('127.0.0.1',8080))
while True:
msg=input(">>: ").strip()
if len(msg) == 0:
continue
client.send(msg.encode('utf-8'))
data=client.recv(1024)
print(data.decode('utf-8'))
udp
服务端
import socketserver
class MyRequestHandler(socketserver.BaseRequestHandler):
def handle(self): # 处理通信
data,server=self.request
server.sendto(data.upper(),self.client_address)
if __name__ == '__main__':
s = socketserver.ThreadingUDPServer(('127.0.0.1', 8080), MyRequestHandler, bind_and_activate=True)
s.serve_forever()
客户端
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'))
元类
单例模式的三种实现方式(*****)
实现方式1:classmethod
import settings
class MySQL:
__instance = None
def __init__(self, ip, port):
self.ip = ip
self.port = port
@classmethod
def singleton(cls):
if cls.__instance:
return cls.__instance
cls.__instance = cls(settings.IP, settings.PORT)
return cls.__instance
# obj1=MySQL("1.1.1.1",3306)
# obj2=MySQL("1.1.1.2",3306)
# print(obj1)
# print(obj2)
obj3 = MySQL.singleton()
print(obj3)
obj4 = MySQL.singleton()
print(obj4)
方式2:元类
import settings
class Mymeta(type):
__instance = None
def __init__(self,class_name,class_bases,class_dic):
self.__instance=object.__new__(self) # Mysql类的对象
self.__init__(self.__instance,settings.IP,settings.PORT)
def __call__(self, *args, **kwargs):
if args or kwargs:
obj = object.__new__(self)
self.__init__(obj, *args, **kwargs)
return obj
else:
return self.__instance
# MySQL=Mymeta(...)
class MySQL(metaclass=Mymeta): # 指定元类为Mymeta
def __init__(self, ip, port):
self.ip = ip
self.port = port
# obj1 = MySQL("1.1.1.1", 3306)
# obj2 = MySQL("1.1.1.2", 3306)
# print(obj1)
# print(obj2)
obj3 = MySQL()
obj4 = MySQL()
print(obj3 is obj4)
方式3:装饰器
import settings
def outter(func): # func = MySQl类的内存地址
_instance = func(settings.IP,settings.PORT)
def wrapper(*args,**kwargs):
if args or kwargs:
res=func(*args,**kwargs)
return res
else:
return _instance
return wrapper
@outter # MySQL=outter(MySQl类的内存地址) # MySQL=》wrapper
class MySQL:
def __init__(self, ip, port):
self.ip = ip
self.port = port
# obj1 = MySQL("1.1.1.1", 3306)
# obj2 = MySQL("1.1.1.2", 3306)
# print(obj1)
# print(obj2)
obj3 = MySQL()
obj4 = MySQL()
print(obj3 is obj4)
进程
1操作系统的组成部分与作用
计算机系统主要是由一个或者多个处理器,主存,硬盘,键盘,鼠标,显示器,
打印机,网络接口及其他输入输出设备组成
作用:
1.隐藏丑陋复杂的硬件接口,提供良好的抽象接口
2.管理,调度进程,并且将多个进程对硬件的竞争变得有序
2什么是并发、并行、串行
串行:一个运行完毕再运行下一个
并行:多个进程是真正意义上一起运行
并发:看起来是同时运行的,本质上还是一个个的运行
3多道技术
多道技术中的多道指的是多个程序
多道技术的实现是为了解决多个程序竞争或者说共享同一个资源(比如cpu)的有序调度问题,解决方式即多路复用,多路复用分为时间上的复用和空间上的复用。
4,单例模式的三种实现方式
进程
1 进程的三种状态
就绪态:
当进程已分配到除CPU意外的所有必要的资源,只要获得处理机便可立即执行
运行态:
当进程已获得处理机,其程序正在处理机上执行
阻塞态:
正在执行的过程,由于等待某个时间发生而无法执行时,便放弃处理机而处于阻塞状态
引起阻塞的事件:
等待IO完成
申请缓冲区不能满足
等待信件(信号)
...
2 并行和并发
并行:多个任务是真的在同时运行,只有多个CPU才有并行的概念
并发:多个任务看起来是在同时运行
3 同步和异步,阻塞和非阻塞
同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不会返回。
异步:当一个进程发起一个函数(任务)调用的时候,不会等函数返回,
而是继续往下执行当,函数返回的时候通过状态、通知、事件等方式通知进程任务完成。
阻塞调用是指调用结果返回之前,当前线程会被挂起(如遇到io操作)。
函数只有在得到结果之后才会将阻塞的线程激活。
非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前也会立刻返回,
同时该函数不会阻塞当前线程