python学习笔记1.5 异常处理和网络编程

异常处理

try:
    names[3]
    data["name"]
except KeyError as e:#抓取一个错误
    print("没有这个key", e)
except (err1, err2) as e:#抓取两个错误
    print("列表操作错误", e)
except Exception as e:#抓取所有错误
    print("出错了", e)
else:
    print("一切正常")
finally:
    print("无论对错都执行")

断言

 assert type(obj.name) is str
print("断言正确")

Socket网络编程

  • Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。

    • 一些其他协议
      协议	    功能用处	                 端口号	  Python 模块
      http        网页访问                     80       httplib, urllib, xmlrpclib
      smtp        发送邮件                     25       smtplib
      dns         域名/IP地址转换              53
      ftp         文件传输                     20       ftplib, urllib
      ssh         为网络服务提供安全性的协议   22
      snmp        简单网络管理协议
      icmp ping   互联网控制报文协议
      dhcp        动态主机配置协议
      ...
      
  • 所有协议本质上都是由:发send和收receive

  • Socket是对以上协议发send和收receive接口的封装

  • 粘包:服务端连续发送数据是,缓存区里两条挨着的数据会黏在一起发送给客户端

  • 解决办法:两次数据发送中间加一次交互

  • OSI七层

    应用
    表示
    会话
    传输 TCP/IP 三次握手,四次断开  1、syn->2、syn/ack->3、ACK  UDP不安全的数据传输
    网络 ip
    数据链路 mac
    物理层
    
  • 一个机器(服务器)上可以开65535个端口(port) 通信的实现要通过IP+port

    Nginx 80
    MySQL 3306
    
  • 发送端流程

    import socket
    socket.TCP/IP
    connect(a.ip,a.port)
    socket.send(hello)
    socket.recv()
    socket.close()
    
      - 实例
      	```python
      	import socket
    
      	client = socket.socket()  # 声明socket类型,同时生成socket连接对象
      	client.connect(("localhost", 9000))
    
      	# client.send(b"Hello World!")#python3里要转字节传输
      	while True:
      		msg = input(">>:").strip()
      		if len(msg) == 0: continue
      		client.send(msg.encode("utf-8"))
      		data = client.recv(1024)  # 收1024字节
      		print("recv:", data.decode())
      	client.close()
      	```
    
  • 接收端(服务端)

    import socket
    socket.TCP/IP
    listen(ip,port)
    waiting()等
    recv()收
    send()回复
    
    • 实例
      	server = socket.socket()  # 声明socket类型,同时生成socket连接对象
      server.bind(("localhost", 9000))  # 绑定到要监听端口
      server.listen(5)  # 监听
      print("我要开始等电话了")
      while True:
          conn, addr = server.accept()  # 等电话打进来
          # conn就是客户端连过来而在服务器端为其生成的一个连接实例
          print(conn, addr)
          print("电话来了")
          while True:
              data = conn.recv(1024)
              print("recv:", data.decode())
              if not data:
                  print("client has lost...")
              conn.send(data.upper())#服务端最多能发送32M
      
      server.close()
      
  • Socket Families(地址簇)

    socket.AF_UNIX  unix本机进程间通信
    socket.AF_INET ipV4
    socket.AF_INET6 ipV6
    
    Socket Types
    socket.SOCK_STREAM #for tcp
    socket.SOCK_DGRAM #for udp
    socket.SOCK_RAW #原始套接字,普通的套接字无法处理ICMP、IGMP的网络报文,而SOCK_RAW可以;其次SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头(可以伪造物理攻击即doc攻击)。
    
ftp server流程
1、读取文件
2、检测文件是否存在
3、打开文件
4、检测文件大小
5、发文件大小给客户端
6、等客户端确认
7、开始边读边发数据
8、发送md5

多任务 - 线程

  • 概念:简单地说就是操作系统可以同事运行多个任务,如同时听歌、用word工作、浏览器上网

  • 单核CPU执行多任务:操作系统让任务交替执行,任务1执行0.01s,任务2执行0.01s,任务,3执行0.01s...

    • 并行:真的多任务
    • 并发:假的多任务(时间片轮转)
  • 线程:

    • 一个程序运行起来之后,一定有一个执行代码的东西,这个东西就叫做线程

    • python的thread模块是比较底层的模块,python的threading模块对thread做了一些包装,可以更加方便的被使用

    • 查看正在运行的线程用:threading.enumerate()

    • 当调用Thread的时候,不会创建线程

    • 当调用Thread创建出来的实例对象的start方法的时候,才会创建线程以及让个这个线程开始运行

    • 同时创建多个子线程,子线程执行的先后顺序是不固定的(随机的)

    • 如果创建Thread时执行的函数,函数运行结束就意味着这个子线程结束

    • 子线程一定先于主线程结束

    • 创建子线程:

      • 通过指定函数创建子线程
        • 创建带参数的线程threading.Thread(target=test1, args=(参数,))
        • target:指定将来这个线程去哪个函数执行代码
        • args:指定将来调用函数的时候传递什么数据过去(args必须是个元组)
      • 通过继承Thread类创建子线程
    • 多线程共享全局变量:

      • 在一个函数中对全局变量进行修改的时候,是否需要用global进行说明,要看是否对全局变量的指向进行了修改
      • 如果修改了指向,那么必须用global,如果仅仅是修改了指向的空间中的数据,此时不必使用global
      • 多线程共享全局变量的时候会存在资源竞争
    • 同步

      • 同步就是协同步调,按预定的先后顺序运行,如:你说完·我再说
      • 进程、线程同步,可以理解为进程或线程A和B一块配合,A执行到一定程度的时候要依靠B的某个结果, 于是停下来,让B运行;B执行,将结果给A;A再继续操作
    • 互斥锁

      • 当多个线程几乎同时修改某一个共享数据的时候,需要进行同步控制
    • 死锁

      • 在线程间共享多个资源的时候,如果两个线程分别占有一部分资源,并且同时等待对方的资源,就会造成死锁

      • 避免死锁

        • 程序设计时要尽量避免(银行家算法)
        • 添加超时时间
进程、线程、协程对比
  • 进程是资源分配单位
  • 线程是操作系统调度的单位
  • 进程切换需要的资源最大,效率很低
  • 线程切换需要的资源一般,效率一般(当然了在不考虑GIL的情况下)
  • 协程切换任务资源很小,效率高
  • 多进程、多线程根据CPU核数不一样可能是并行的,但是协程是在一个线程中所以是并发
SocketServer:实现并发处理
SocketServer.TCPServer
SocketServer.UDPServer
SocketServer.UnixStreamServer
SocketServer.UnixDatagramServer
  • 1、你必须自己创建一个请求处理类,并且这个类要继承BaseRequestHandler,并且还有重写父亲类里的handler()
  • 2、你必须实例化TCPServer,并且传递server ip 和你上面创建的请求处理类,给这个TCPServer
  • 3、调用handle_request()和server_forever()方法
    • server.handle_request()#只处理一个请求
    • server.server_forever()#处理多个请求,永远执行
  • 4、调用server_close()去关闭这个socket
    • 实例
      	import socketserver
      
      	class MyTCPHandler(socketserver.BaseRequestHandler):
      		'''
      			继承socketserver,重写handle方法
      		'''
      
      		def handle(self):
      			while True:
      				try:
      					# self.request是TCP socket 链接到客户端
      					self.data = self.request.recv(1024).strip()
      					print("{} worte:".format(self.client_address[0]))
      					print(self.data)
      					self.request.sendall(self.data.upper())
      				except ConnectionResetError as e:
      					print("err:",e)
      					break
      
      	if __name__ == "__main__":
      		HOST, PORT = "localhost", 9000
      
      		server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)#多线程
      		# server = socketserver.ForkingTCPServer((HOST, PORT), MyTCPHandler)#多进程(linex)
      
      		server.serve_forever()
      

练习:开发一个支持多用户在线的FTP程序

要求:

    1、用户加密认证
    2、允许同时多用户登录
    3、每个用户有自己的home目录,且只能访问自己的home目录
    4、对用户进行磁盘配额,每个用户的可用空间不同
    5、允许用户在ftp server上随意切换目录
    6、允许用户查看当前目录下的文件
    7、允许上传和下载文件,保证文件的一致性
    8、文件传输过程中显示进度条
    9、附加功能:支持文件断点续传
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值