• Python学习-day7 类 部分socket


    这周还是继续关于类的学习,在面向对象的学习过程中又学习了网络编程,并且提交了编写FTP的作业。

    复习一下类的相关概念和定义

         属性
              实例变量:内存中
              类变量: 类的内存,实例共享
              私有属性__var
         方法
              构造方法: 初始化
              析构方法: 实例销毁的时候
              私有方法   
              静态方法:只是名义上的归类管理,实际上在静态方法中无法访问类中的任何属性。            
              属性方法:把一个方法变成静态属性         
              类方法:可以使用类变量,不能访问实例中的变量 
              
    对象:一个类的实例
         封装
              把一些功能的实现细节,不对外暴露          
         继承
              代码的重用
              单集成
               多继承
                    2.7 经典类,深度优先     新式类,广度优先
                    3.x 均是广度优先
                    class Foo(object)
                   def __init__(self,name,age,sex,salary,course):
                        super(Foo,self).__init__(name,age,sex)
                        self.salary = salary
                        self.course = course          
         多态
              接口的重用,一种接口,多种实现
     
     下面是一个Socket通信的实例:
    Server端
    #Authon Ivor
    import socket
    import json
    import os
    
    ip = ('localhost',9999)
    s = socket.socket()
    s.bind(ip)
    s.listen(5)
    
    while True:
        print("等待连接中....")
        conn,client_addr = s.accept()
        print("有用户主动接入:", conn, client_addr)
        while True:
            data = conn.recv(4096)
            data = json.loads(data.decode('utf-8'))
            if data.get('action') is not None:
                if data['action'] == 'put':
                    file_obj = open(data['file_name'],'wb')
                    receive_size = 0
                    file_size = data['file_size']
                    while receive_size < file_size:
                        recv = conn.recv(4096)
                        file_obj.write(recv)
                        receive_size += len(recv)
                        print(file_size,receive_size)
                    file_obj.close()
                    print("File receive complete!")
                elif data['action'] == 'get':
                    pass
    View Code

    Client端

    #Authon Ivor
    import os
    import json
    import socket
    
    client = socket.socket()
    client.connect(('localhost',9999))
    while True:
        choice = input(">>>:")
        if len(choice) == 0:continue
        cmd_list = choice.split()
        if cmd_list[0] == 'put':
            if cmd_list[-1]:
                file_name = cmd_list[-1]
                if os.path.isfile(file_name):
                    base_filename = file_name.split("/")[-1]
                    file_size = os.path.getsize(file_name)
                    file_obj = open(file_name,'rb')
                    data_header = {
                        "action":"put",
                        "file_name":base_filename,
                        "file_size":file_size
                    }
                    client.send(json.dumps(data_header).encode('utf-8'))
                    for line in file_obj:
                        client.send(line)
                    print("File send complete.".center(50,'-'))
                else:
                    print("File is not exists.")
            else:
                print("Need a file...")
        elif cmd_list[0] == 'get':
            pass
        else:
            print("Wrong input.")
    View Code


    如果想要实现多并发连接也很简单,Socket自带了多线程的TCP服务

    需要定义一个继承socketserver.BaseRequestHandler的Handler,

    并且重定义handler函数,通过self.request.recv()/self.request.send()

    #Authon Ivor
    import socketserver
    
    class MyHandelclass(socketserver.BaseRequestHandler):
    
        def handle(self):
            while True:
                self.data = self.request.recv(4096)
                print(self.client_address)
                print(self.data)
                self.request.sendall(self.data.upper())
    
    if  __name__ == '__main__':
       server = socketserver.ThreadingTCPServer(('localhost',9999),MyHandelclass)
       server.serve_forever()
    View Code

    Client端不需要变动

    #Authon Ivor
    import os
    import json
    import socket
    
    client = socket.socket()
    client.connect(('localhost',9999))
    while True:
        choice = input(">>>:")
        if len(choice) == 0:continue
        client.send(choice.encode('utf-8'))
        data =client.recv(1024)
        print(data)
    View Code

    下一个重要的知识点,反射,通过字符串判断类中是否存在这个方法

    #Authon Ivor
    def bark(self):
        print("%s   is yelling!" % self.name )
    
    
    class Dog(object):
    
        def __init__(self,name):
            self.name = name
    
        def eat(self):
            print("%s is eating!" % self.name)
    
    d= Dog("Wangwang")
    choice = input(">>>:")
    
    if hasattr(d,choice):
        func = getattr(d,choice)
        func()
    else:
        setattr(d,choice,bark) #d.choice = bark
        func = getattr(d,choice)
        func(d)
    View Code


    异常处理

    #Authon Ivor
    
    name = [0,1,2]
    dic = {}
    
    try:
        name[3]
    except IndexError as e :
        print(e)
    try:
        dic['666']
    except KeyError as e:
        print("KeyError",e)
    
    except Exception as e:
        print("可以抓到任何错误!")
    else:
        print("没有错误时我会运行!")
    finally:
        print("不管怎么样,我都会运行!")
    
    # 常用异常
    # AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
    # IOError 输入/输出异常;基本上是无法打开文件
    # ImportError 无法引入模块或包;基本上是路径问题或名称错误
    # IndentationError 语法错误(的子类) ;代码没有正确对齐
    # IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
    # KeyError 试图访问字典里不存在的键
    # KeyboardInterrupt Ctrl+C被按下
    # NameError 使用一个还未被赋予对象的变量
    # SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
    # TypeError 传入对象类型与要求的不符合
    # UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
    # 导致你以为正在访问它
    # ValueError 传入一个调用者不期望的值,即使值的类型是正确的
    View Code

    类的其他特殊成员方法

    #Authon Ivor
    
    class Foo(object):
        #定义类的原类
        __metaclass__ = type
    
        #类中所有的方法和属性
        #__dict__
    
        #构造函数,创建对象时调用
        def __init__(self,name,age):
            super(Foo,self).__init__()
            self.age = age
            self.name = name
        #定义对象的调用方式
        def __call__(self, *args, **kwargs):
            print("I'm the __call__ .")
        #打印对象时,使用这个函数的返回值
        def __str__(self):
            return "%s" % self.name
    
        def __new__(cls, *args, **kwargs):
            print("I'm the __new__!")
            return object.__new__(cls)
        def __del__(self):
            pass
    
    f = Foo("ivor",27)
    f()
    
    #类的第二种定义方法,一切皆对象,类也是对象,源于type
    def func(self):
        print("hello %s"%self.name)
    
    def __init__(self,name,age):
        self.name = name
        self.age = age
    Foo = type('Foo',(object,),{'func':func,'__init__':__init__})
    f = Foo("jack",22)
    f.func()
    View Code

    以下是这次作业的ReadMe

    程序说明:
        1.启动服务端
      ./FTP_Server/bin/ftp_server.py start
      端口号为9999,写入了settings的配置文件里。
        2.启动客户端
      ./FTP_Client/ftp_client -s localhost -p 9999 -u Ivor -P abc123
      Ivor abc123  /  Jack abc123
      用户名密码也可以连接后输入,有两个用户,写在了accounts里。
        3.连接成功后,用户默认所在目录为家目录。
    程序功能:
        1.put  --md5(可选)
     向服务器上传文件,服务器会检验是否超过了分配空间,有空间则上传,空间不足则返回错误。md5一致性检验为可选项
        2.get  --md5(可选)
     从服务器下载文件。md5一致性检验为可选项
        3.ls
     列出当前目录的文件。试用于linux系统
        4.dir
     列出当前目录的文件。试用于linux系统和windows系统

  • 相关阅读:
    cyren提供安全规则
    AC自动机——1 Trie树(字典树)介绍
    代码静态分析工具——splint的学习与使用
    Aria2+WebUI,迅雷倒下之后的代替品
    立华科技
    centos平台基于snort、barnyard2以及base的IDS(入侵检测系统)的搭建与测试及所遇问题汇总
    Iperf使用方法与参数说明
    网络基本功(一):细说网络传输
    TCP窗口扩大选项
    TCP Nagle算法&&延迟确认机制
  • 原文地址:https://www.cnblogs.com/Darksugar/p/6688963.html
Copyright © 2020-2023  润新知