zoukankan      html  css  js  c++  java
  • 人生苦短,我用python-- Day8

    目录                          

      动态导入模块

      断言

      socket高级编程

      socketServer

    动态导入模块                                

    先看一下目录结构

    动态导入模块有两种方式,我们先来看第一种:

    # Author:Sean sir
    # 这种情况下导入的是lib目录,如果想调用lib目录下的aa模块,需要在继续往下调用
    mod = __import__('lib.aa') obj = mod.aa.C() print(obj.name)

    我们来看第二种方法:

    # Author:Sean sir
    # 这种情况下导入的直接是aa模块,如果想用aa模块里面的方法,直接调用就可以了。
    import importlib mod = importlib.import_module('lib.aa') obj = mod.C() print(obj.name)

     断言                                  

    关键字:assert

    作用:提高逼格,在操作后面代码前先进行判断。与if进行判断相差无几

    代码:

    # Author:Sean sir
    user_input = input('>>>:')
    assert type(user_input) is str
    print('aaa')
    
    # 输出
    >>>:asdf
    aaa

    socket高级编程                                

    写一个ssh的工具

    # Author:Sean
    import socket,os
    server = socket.socket()
    server.bind(('127.0.0.1',8888))
    server.listen()
    while True:
        print('我要开始等电话了')
        conn,add = server.accept()
        while True:
            print('电话来了')
            data = conn.recv(1024)
            if not len(data):break
            data = data.decode('utf-8')
            print(type(data))
            cmd_str = os.popen(data).read()
            len_cmd_str = str(len(cmd_str)).encode('utf-8')
            conn.send(len_cmd_str)
            conn.send(cmd_str.encode('utf-8'))
        server.close()
    ssh server
    # Author:Sean sir
    import socket
    client = socket.socket()
    client.connect(('127.0.0.1',8888))
    while True:
        user_input = input('>>:').strip()
        if not len(user_input):
            continue
        client.send(user_input.encode('utf-8'))
        data_1 = int(client.recv(1024).decode('utf-8'))
        recv_size = 0
        recv = b''
        while recv_size != data_1:
            recv_data = client.recv(1024)
            recv_size += len(recv_data)
            recv += recv_data
        else:
            print(recv.decode('utf-8'))
            print('收取执行命令结果完成!')
    client.close()
    ssh client

    上面的server如果两条send命令在一起,那么会出现粘包的问题,粘包:就是说系统会把两个包同时当做一个包的数据发送过去,解决上述问题,继续看代码:

     其实很简单,只需要在两个send中间加一个sleep时间就可以了。

    # Author:Sean
    import socket,os,time
    server = socket.socket()
    server.bind(('127.0.0.1',8888))
    server.listen()
    while True:
        print('我要开始等电话了')
        conn,add = server.accept()
        while True:
            print('电话来了')
            data = conn.recv(1024)
            if not len(data):break
            data = data.decode('utf-8')
            print(data)
            cmd_str = os.popen(data).read()
            len_cmd_str = str(len(cmd_str)).encode('utf-8')
            conn.send(len_cmd_str)
            time.sleep(0.5)
            conn.send(cmd_str.encode('utf-8'))
        server.close()
    ssh server
    # Author:Sean sir
    import socket
    client = socket.socket()
    client.connect(('127.0.0.1',8888))
    while True:
        user_input = input('>>:').strip()
        if not len(user_input):
            continue
        client.send(user_input.encode('utf-8'))
        data_1 = int(client.recv(1024).decode('utf-8'))
        recv_size = 0
        recv = b''
        while recv_size != data_1:
            recv_data = client.recv(1024).decode('utf-8')
            recv_size += len(recv_data)
            # recv += recv_data
            print(recv_data)
        else:
            print(recv.decode('utf-8'))
            print('收取执行命令结果完成!')
    client.close()
    ssh client

     上面的实现形式有没有感觉到low啊,不能时时的返回数据,我们来一个高大上的解决办法

     解决思路大概是: 当我发送了执行结果大小后,然后在接受一个客户端发送过来的确认包,如果接受到了,那么继续发送执行结果,如果没有接收到那么就等待,

     这里就不会出现粘包的问题了。

    # Author:Sean
    import socket,os,time
    server = socket.socket()
    server.bind(('127.0.0.1',7777))
    server.listen()
    while True:
        print('我要开始等电话了')
        conn,add = server.accept()
        while True:
            print('电话来了')
            data = conn.recv(1024)
            if not len(data):break
            data = data.decode('utf-8')
            print(data)
            cmd_str = os.popen(data).read()
            len_cmd_str = str(len(cmd_str)).encode('utf-8')
            conn.send(len_cmd_str)
            #time.sleep(0.5)
            ack = conn.recv(1024)
            print(ack)
            conn.send(cmd_str.encode('utf-8'))
        server.close()
    ssh server
    # Author:Sean sir
    import socket
    client = socket.socket()
    client.connect(('127.0.0.1',7777))
    while True:
        user_input = input('>>:').strip()
        if not len(user_input):
            continue
        client.send(user_input.encode('utf-8'))
        data_1 = int(client.recv(1024).decode('utf-8'))
        client.send('我已经做好接受命令准备了!loser发送命令吧!'.encode('utf-8'))
        recv_size = 0
        recv = b''
        while recv_size != data_1:
            recv_data = client.recv(1024).decode('utf-8')
            recv_size += len(recv_data)
            # recv += recv_data
            print(recv_data)
        else:
            print(recv.decode('utf-8'))
            print('收取执行命令结果完成!')
    client.close()
    ssh client

    写一个ftp的工具

    # Author:Sean
    import socket,os,hashlib
    server = socket.socket()
    server.bind(('127.0.0.1',7777))
    server.listen()
    while True:
        print('等待新的客户端连接')
        conn,add = server.accept()
        while True:
            print('等待新指令:')
            data = conn.recv(1024)
            if not len(data):
                print('客户端已断开。。。。。')
                break
            cmd,filename = data.decode().split()
            # print(filename)
            if os.path.isfile(filename):
                f = open(filename,'rb')
                m = hashlib.md5()
                file_size = os.stat(filename).st_size
                conn.send(str(file_size).encode())  # 发送一个文件大小到客户端
                # print(str(file_size))
                ack_info = conn.recv(1024) # 等待客户端发送收到确认信息
                for line in f:
                    conn.send(line)
                f.close()
        server.close()
    ftp server
    # Author:Sean sir
    import socket
    client = socket.socket()
    client.connect(('127.0.0.1',7777))
    while True:
        user_input = input('>>:').strip()
        if not len(user_input):continue
        if user_input.startswith('get'):
            client.send(user_input.encode())
            server_response = client.recv(1024)
            print('Server response:',server_response)
            client.send(b'ready to recv file!')
            file_total_size = int(server_response.decode())
            received_size = 0
            filename = user_input.split()[1]
            f = open(filename+'_new','wb')
            while received_size < file_total_size:
                data = client.recv(1024)
                received_size += len(data)
                f.write(data)
                print(received_size,file_total_size)
            else:
                print('file recv done')
                f.close()
    client.close()
    ftp client

    优化上面的ftp,给上面的ftp传输后的文件md5下,查看下两个文件md5是否一致,最后发送md5的时候,可能会出现粘包的问题,在客户端我们稍微做了处理,当接受的剩余文件小于1024时候的,最后只收文件总大小减去接受到的文件大小的字节数。

    # Author:Sean
    import socket,os,hashlib
    server = socket.socket()
    server.bind(('127.0.0.1',7777))
    server.listen()
    while True:
        print('等待新的客户端连接')
        conn,add = server.accept()
        while True:
            print('等待新指令:')
            data = conn.recv(1024)
            if not len(data):
                print('客户端已断开。。。。。')
                break
            cmd,filename = data.decode().split()
            # print(filename)
            if os.path.isfile(filename):
                f = open(filename,'rb')
                m = hashlib.md5()
                file_size = os.stat(filename).st_size
                conn.send(str(file_size).encode())  # 发送一个文件大小到客户端
                # print(str(file_size))
                ack_info = conn.recv(1024) # 等待客户端发送收到确认信息
                for line in f:
                    m.update(line) # 哈希这一行文件
                    conn.send(line)
                f.close()
                conn.send(m.hexdigest().encode())
        server.close()
    ftp server
    # Author:Sean sir
    import socket,hashlib
    client = socket.socket()
    client.connect(('127.0.0.1',7777))
    while True:
        user_input = input('>>:').strip()
        if not len(user_input):continue
        if user_input.startswith('get'):
            client.send(user_input.encode())
            server_response = client.recv(1024)
            print('Server response:',server_response.decode())
            client.send(b'ready to recv file!')
            file_total_size = int(server_response.decode())
            received_size = 0
            filename = user_input.split()[1]
            f = open(filename+'_new','wb')
            m = hashlib.md5()
            while received_size < file_total_size:
                if file_total_size - received_size < 1024:
                    size = file_total_size - received_size
                else:
                    size = 1024
                data = client.recv(size)
                m.update(data)
                received_size += len(data)
                f.write(data)
            else:
                print('文件接收完毕!')
                f.close()
            server_file_md5 = client.recv(1024)
            if server_file_md5.decode() == m.hexdigest():
                print('经过md5检验,两个文件完全相同!')
    client.close()
    ftp client

     SocketServer                              

    不同于Socket的是,这个可以处理多个请求,socket只能处理单线程。

    创建一个SocketServer大概分如下几步:

    第一步:创建一个一个请求处理类,并且这个类要集成BaseRequestHandler,并且还要重写父类的handle()方法。

    第二步:你必须实例化一个类,我们常用(TCPServer),并且传递server IP和你上面穿件的请求处理类给这个TCPServer

    第三步:可以是用handle_request()或server_forever()进行处理请求,前者只处理一个请求,后者可以处理多个请求,永久执行

    第四步:调用server_close()关闭socket

    使用socketServer来简单实现以下socket编程,客户端输入数据,返回大写

    # Author:Sean sir
    import socketserver
    class MyTCPHandler(socketserver.BaseRequestHandler):
        def handle(self):
            while True:
                self.data = self.request.recv(1024).strip()
                if not self.data :
                    print('主机断开!')
                    break
                print("{} wrote:".format(self.client_address[0]))
                print(self.data)
                self.request.sendall(self.data.upper())
    if __name__ == "__main__":
        HOST, PORT = '127.0.0.1', 8888
        server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)
        server.serve_forever()
    socketServer_server
    # Author:Sean sir
    import socket
    client = socket.socket()
    client.connect(('127.0.0.1',8888))
    while True:
        user_input = input('>>:').strip()
        if not len(user_input):
            continue
        client.send(user_input.encode('utf-8'))
        data = client.recv(1024)
        print(data.decode('utf-8'))
    client.close()
    socketServer_client

    调皮的大王说,现在这种情况,依旧不能实现多线程,那就继续往下看,到底实现多线程!

     我们只需要把

    server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)

    换成

    server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)

    就可以了,就是这么简单,我也惊呆了!!!!

    0

  • 相关阅读:
    Postman几种常用方式
    PL/SQL 循环结构
    【oracle】解锁oracle用户,unlock
    四则运算题2
    有关Botton的用法(一)
    SQLiteOpenHelper的使用
    用Toast来增加调试效率的小技巧
    汇编语言-比较字符串
    正向代理和反向代理
    redis安装与配置
  • 原文地址:https://www.cnblogs.com/xinzhiyu/p/5861229.html
Copyright © 2011-2022 走看看