python_day8_ importlib、断言 / socket ssh客户端(1.一次性读取 2.黏包) / socket server / FTP

python_ importlib、断言 / socket ssh客户端(1.一次性读取 2.黏包) / socket server / FTP

在这里得感谢,老师Alex金角大王(路飞学城IT)
Python(给兄弟们挂个🔗)

Alex老师博客

python边写边更… 这张有点多,QAQ…代码写的有点乱,hhhh我就是Alex说的山炮写的代码吧/狗头/狗头

一、_ _ import _ _ / importlib、断言:

(1)_ _ import _ _的使用:(以"字符串"的形式,导入文件)

在这里插入图片描述
(在lib目录下,写一个aa.py,再在aa里面写一个“类”,方便调用)

class man(object):
    def __init__(self,name):
        self.name = name
lib = __import__("lib.aa")#这个内置方法,给予句柄,是目录文件;而不是aa
print(lib.aa.man("alex").name)#调用lib下的aa,在直接调用man,实例化姓名,属性输出

(2):一般使用importlib.import_moduel:(直接可以调用到“目录下的文件”)

import importlib

aa = importlib.import_module("lib.aa")

print(aa.man("Tom").name)

(3)“断言”:assert:(判断什么就是什么…例如:“abcd”是一段字符串)

#Author:Jony c
#!/usr/bin/env  python
# -*- coding:utf-8 -*-

assert type("abcd") is str
print("字符串无疑")

(这个“判断”,不是赋值句柄,然后print…True/Fluse;而是“阻断”后方程序)

(4)回顾一下,上节课学的,socket网络编程:建议自己写一遍…

server:

#Author:Jony c
#!/usr/bin/env  python 
# -*- coding:utf-8 -*-
import socket

server = socket.socket()
server.bind(("localhost",9999))#元组形式
server.listen(5)#开始监听

while True:
    conn,addr = server.accept()#conn是"实例化"的一个对象,adder是client地址
    #waiting“等电话阶段”
    while True:
        print("电话来了...")
        data = conn.recv(1024)#接收的bytes类型
        print(">>>",data)
        if not data:break
        conn.send(data.upper())#bytes类型,也可以用“upper”方法
server.close()

client:

#Author:Jony c
#!/usr/bin/env  python 
# -*- coding:utf-8 -*-

import socket

client = socket.socket()#创建服务端
client.connect(("localhost",9999))#连接,元组形式

while True:
    msg = input(">>>:").strip()
    if not msg : continue
    client.send(msg.encode("utf-8"))#传输时,用bytes
    client.recv(1024)#最大接收1024k

client.close()

conclude:
1.客服端:connect / send /recv
2.服务端:bind / listen / conn,addr = accpet() / recv /send

二、socket.ssh:

1.一次性读取:

(1):client传输“执行”命令:

client:

import socket

client =socket.socket()

client.connect(("localhost",9999))

while True:

    msg = input(">>>:").strip()
    if len(msg) ==0:continue
    client.send(msg.encode("utf-8"))
    recv_result = client.recv(1024)
    print(recv_result.decode())#解码操作
client.close()

server:

import  socket,os

server = socket.socket()
server.bind(("localhost",9999))
server.listen(5)
while True:
    conn,addr =server.accept()
    print("the is coming....")
    while True:
        data = conn.recv(1024)
        print(data)
        if not data:
            print("client  is losing。。。。")
            break
        cmd = os.popen(data.decode()).read()
        print("指令:",cmd)#如果是错误的命令,cmd就是“空”,客服端就会一直等...“卡死”
        if len(cmd) == 0:
            conn.send("the input code is invailded。。。。".encode("utf-8"))
        conn.send(cmd.encode("utf-8"))
        print("have sending。。。")

server.close()

conclude:
1.如果是“错误”指令,server这边执行不了,cmd是空的,client就会一直等这个命令,就会卡住;就必须加个if,返回告诉client

2.还有就是指令执行结果,如果是大于8k,缓存区根本存不了,得分好几次发送;缓存区(①.满了发送 ②.到时间了,send强制发送)

(2):client"一直收"操作:

tips:

a="汉字"
print(len(a))
print(len(a.encode("utf-8")))

result:2
6
中文,编码字节lens为3;所以你“事先”的文件指令(可能含有“中文”)长度 ≠ client端接收到的bytes(字节长度);server中cmd,先encode,再len,最后send size;否则后面会报错…

server:

import  socket,os

server = socket.socket()
server.bind(("localhost",9999))
server.listen(5)
while True:
    conn,addr =server.accept()
    print("the is coming....")
    while True:
        data = conn.recv(1024)
        print(data)
        if not data:
            print("client  is losing。。。。")
            break
        cmd = os.popen(data.decode()).read()
        print("指令:",cmd)#如果是错误的命令,cmd就是“空”,客服端就会一直等...“卡死”
        if len(cmd) == 0:
            conn.send("the input code is invailded。。。。".encode("utf-8"))
        conn.send(str(len(cmd.encode("utf-8"))).encode("utf-8"))#先把指令执行结果,大小发过去
        conn.send(cmd.encode("utf-8"))
        print("have sending。。。")

server.close()

在这里插入图片描述
client:

import socket

client =socket.socket()

client.connect(("localhost",9999))


while True:
    msg = input(">>>:").strip()
    if len(msg) ==0:continue
    client.send(msg.encode("utf-8"))
    recv_size = client.recv(1024)#1.接收到文件的“大小”
    print(recv_size.decode())
    cmd_size = int(recv_size.decode())
    recving_size =0#只能放在里面,放外面的话会“卡死”
    recving_data = b""#存一个空字节
    while recving_size < cmd_size:#文件大小不够,一直接受
        data = client.recv(1024)#2.一直接受文件
        recving_size += len(data)
        recving_data += data

    else:
        print("have recv done。。。",recving_size,recving_data.decode())
client.close()

在这里插入图片描述
conclude:
1."指令"不存在的话,if,别让client一直等
2.汉字的“str”长度 ≠ “bytes”长度
3.recving_size / recving_data ,放在while recv_size < total_ size 外面;

2.黏包:

1.什么是黏包???

conn.send(str(len(cmd.encode("utf-8"))).encode("utf-8"))#先把指令执行结果,大小发过去
conn.send(cmd.encode("utf-8"))#再发送文件执行

像这种,如果你连续send两次,缓存区就会把“它们”当成一条指令;放在缓冲区,发送过去;在client端可能会有size 和 data 连在一起的效果,这种效果就是“黏包”…

server:

 conn.send(str(len(cmd.encode("utf-8"))).encode("utf-8"))#先把指令执行结果,大小发过去
 client_confrim =  conn.recv(1024)#enen。。在这里我等你客服端的“确认”,强行交互,让两次send分开
 conn.send(cmd.encode("utf-8"))#再发送文件执行在这里插入代码片

client:

client.send("i am already...".encode("utf-8"))

3.文件操作:

server:

import  socket,os

server = socket.socket()
server.bind(("localhost",9999))
server.listen(5)
while True:
    conn,addr =server.accept()
    print("the is coming....")
    while True:
        cmd,filename = conn.recv(1024).decode().split()
        print(filename)
        if os.path.isfile(filename):#如果是一个文件
            f = open(filename,"rb")
            file_size = os.stat(filename).st_size#获取文件大小
            #1.发送total_size
            conn.send(str(file_size).encode("utf-8"))
            #2.防止黏包
            conn.recv(1024)
            #3.send data
            for line in f:
                conn.send(line)
            f.close()
server.close()

client:

#Author:Jony c
#!/usr/bin/env  python 
# -*- coding:utf-8 -*-
import socket

client = socket.socket()
client.connect(("localhost",9999))

while True:
    msg = input(">>>:").strip()
    if len(msg) ==0:continue
    if msg.startswith("get"):
           client.send(msg.encode("utf-8"))#发送命令
           #1.接收total_size
           flied_size = client.recv(1024)
           print(flied_size)
           #2.防止黏包
           client.send("i am already....".encode("utf-8"))
           filed_size2 = int(flied_size.decode())
           received_size = 0
           f = open(msg.split()[1]+ "new",'wb')
           #3.循环接收size / data
           while  received_size < filed_size2 :
                  data = client.recv(1024)#接收数据
                  received_size += len(data)
                  f.write(data)
           else:
               print("file have copy down。。。 ")
               f.close()
client.close()

conclude:

server:1.发送total_size(os.stat(fliename).st_size) 2.防止黏包 3.send data
client:1.接收total_size 2.防止黏包 3.循环接收size / data

4.ssh:(导入了md5加密):

server:

import  socket,os,hashlib

server = socket.socket()
server.bind(("localhost",9999))
server.listen(5)
while True:
    conn,addr =server.accept()
    print("the is coming....")
    while True:
        cmd,filename = conn.recv(1024).decode().split()
        print(filename)
        if os.path.isfile(filename):#如果是一个文件
            f = open(filename,"rb")
            file_size = os.stat(filename).st_size#获取文件大小
            m = hashlib.md5()
            #1.发送total_size
            conn.send(str(file_size).encode("utf-8"))
            #2.防止黏包
            conn.recv(1024)
            #3.send data
            for line in f:
                m.update(line)#md5加密
                conn.send(line)
            f.close()
            conn.send(m.hexdigest().encode("utf-8"))#服务端传过去
server.close()

client:

#Author:Jony c
#!/usr/bin/env  python 
# -*- coding:utf-8 -*-
import socket,hashlib

client = socket.socket()
client.connect(("localhost",9999))

while True:
    msg = input(">>>:").strip()
    if len(msg) ==0:continue
    if msg.startswith("get"):
           client.send(msg.encode("utf-8"))#发送命令
           #1.接收total_size
           flied_size = client.recv(1024)
           print(flied_size)
           #2.防止黏包
           client.send("i am already....".encode("utf-8"))
           filed_size2 = int(flied_size.decode())
           received_size = 0
           m = hashlib.md5()
           f = open(msg.split()[1]+ "new",'wb')
           #3.循环接收size / data
           while  received_size < filed_size2 :
                  data = client.recv(1024)#接收数据
                  m.update(data)#客户端循环md5加密
                  received_size += len(data)
                  f.write(data)
           else:
               print("file have copy down。。。 ")
               f.close()
           print("client_md5",m.hexdigest())#客服端循环接收到的md5
           print("server_md5",client.recv(1024))#服务端传过来的md5
client.close()

服务端在最后send md5 ,可能和上面的send date,又发生“黏包”…

deal:
在这里插入图片描述
client:

#Author:Jony c
#!/usr/bin/env  python 
# -*- coding:utf-8 -*-
import socket,hashlib

client = socket.socket()
client.connect(("localhost",9999))

while True:
    msg = input(">>>:").strip()
    if len(msg) ==0:continue
    if msg.startswith("get"):
           client.send(msg.encode("utf-8"))#发送命令
           #1.接收total_size
           flied_size = client.recv(1024)
           print(flied_size)
           #2.防止黏包
           client.send("i am already....".encode("utf-8"))
           filed_size2 = int(flied_size.decode())
           received_size = 0
           m = hashlib.md5()
           f = open(msg.split()[1]+ "new",'wb')
           #3.循环接收size / data
           while  received_size < filed_size2 :
                  #加一个if判断
                  if filed_size2 - received_size > 1024 :
                      size =1024
                  else:#有多少,收多少
                      size = filed_size2 - received_size
                      print("the last size:",size)
                  data = client.recv(size)#接收数据
                  m.update(data)#客户端循环md5加密
                  received_size += len(data)
                  f.write(data)
           else:
               print("file have copy down。。。 ")
               f.close()
           print("client_md5",m.hexdigest())#客服端循环接收到的md5
           print("server_md5",client.recv(1024))#服务端传过来的md5
client.close()

三、socket.server:

(一种封装,简化了“server”服务端,可以实现多并发)(大概有几类…)

1.class socket.TCPServer(server_address,requesthandlecalss)

2.class socket.UDPServer(server_address,requesthandlecalss)
3.class socket.UnixStreamServer(server_address,requesthandlecalss)
4.class socket.UnixDatagramServer(server_address,requesthandlecalss)

(会有这种继承关系:)
在这里插入图片描述
(主要在创建的时候,很简单;大概分这么几步:)
1.创建一个"请求处理类",class requesthandle,这个要继承(socketserver.BaseRequestHandle);而且在他的(def handle)方法里,实现具体的交互内容;
2.实例化一个TCPserver(客户端地址,定义过的请求处理类)
3.server.handle_request()#只处理一次(一般不用);server.server_forever#多次处理

2."服务端"的class封装:

import socketserver

class MyTCPHandler(socketserver.BaseRequestHandler):
    def handle(self):#handle里面实现,交互的内容;继承父类的“BaseRequest”,父类里面的handle什么都没写
        while True:
            try:
                self.data = self.request.recv(1024).strip()
                print("{} wrote:".format(self.client_address[0]))
                print(self.data)
            except ConnectionResetError as e:#socket.server里面的在(client断开时),统一报的这种错误
                print("err",e)
                break
if __name__ == "__main__":
    HOST, PORT = "localhost", 9999
    # Create the server, binding to localhost on port 9999
()
    server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)
    #实例化一个“服务端”,把地址和requesthandle,传给对象
    server.serve_forever()#执行多次

3.实现多用户并发 :(实现多个用户并行交互):

(实例化的时候,socketserver.ThreadingTCPserver(),就这样就行…)

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

"BaseRequest"的一些方法:

"""
1.fileno()文件描述符

2.serevr_forver(poll_interval = 0.5)
这个请求,会一直执行,直到一个明确的shutdown()请求;在返回shutdown()时,同样也会执行一个service_actions()
poll(检查),以poll_interval = 0.5,0.5s的速度去“扫描”有没有这个shutdown

3.allow_reuse_address
#在client突然断开时,server会一直等到他发送请求(大约30多秒);这条命令可以让server不用去等,重新使用地址
(server.setsockopt(scoket.SOL_SOCKET,socket.so_REUSERADDER,1)...这种在)
"""

在这里插入图片描述
这个是“父类”的方法,setup在(_ _ init _ _)、hanlde(try) 和 set up (finally);你可以在请求(先后);加一些你自己的“操作”

四、FTP程序开发:

(client用类作,server用socket.server封装,实现“文件操作”run file、文件上传 put file 和 文件下载 get file )

1.实现一个简单的FTP:

在这里插入图片描述
server:

import socketserver,os,json

class MyTCPHandle(socketserver.BaseRequestHandler):


     def run(self,*args):
        filename =args[0]['filname']
        print(filename)#调试
        cmd_result = os.popen(filename).read()
        print(cmd_result)#调试
        self.request.send(str(len(cmd_result.encode("utf-8"))).encode("utf-8"))#1.传大小
        self.request.recv(1024)#2.防止黏包
        while True:#3.发送数据
          self.request.send(cmd_result.encode("utf-8"))
        else:
            self.request.close()

     def get(self,*args):#调试(√)
        filename =args[0]['filname']
        print(filename)#调试
        self.request.send(str(os.stat(filename).st_size).encode("utf-8"))#1.发送文件大小
        f = open(filename,'rb')
        self.request.recv(1024)#2.防止黏包
        for line in f:#3.传送数据
            self.request.send(line)
        else:
            self.request.close()
            f.close()
        print("写完了...")

     def put(self,*args):#调试完成(√)
        filename =args[0]['filname']
        filesize = args[0]["filsize"]
        total_size = filesize#1.接收文件大小
        print(total_size)
        self.request.send("i am already...".encode("utf-8"))#2.防止黏包
        recevied_size = 0
        f = open(filename,"wb")
        print("打开了")
         #3.循环接收date
        while recevied_size < int(total_size):
               if int(total_size) - recevied_size > 1024:
                   size = 1024
               else:
                   size = int(total_size) -recevied_size

               date3 = self.request.recv(size)
               recevied_size +=len(date3)
               f.write(date3)
               print("正在写....")
        else:
            print("写完了...")
            self.request.close()
            f.close()


     def handle(self):

        while True:
          try:
            self.date = self.request.recv(1024).strip()
            print("{}writen".format(self.client_address[0]))
            print(self.date)

            cmd_recv = json.loads(self.date.decode())
            print(cmd_recv)#调试成功
            action = cmd_recv["action"]
            print(action)#调试成功
            if hasattr(self,action):
               func = getattr(self,action)
               print("调试")
               func(cmd_recv)#把字典传进去
          except (OSError,ConnectionError) as e:
              print("error",e)
              break



if __name__ == "__main__":
    HOST,PORT = "localhost",9999
    server = socketserver.ThreadingTCPServer((HOST,PORT),MyTCPHandle)
    server.serve_forever()

client:

#Author:Jony c
#!/usr/bin/env  python 
# -*- coding:utf-8 -*-
#这里用class类,去实现;

import socket,os,hashlib,json
class FTP(object):
    def __init__(self):
        self.client = socket.socket()#实例化client
    def connect(self,ip,port):
        self.client.connect((ip,port))#连接
    def help(self,*arges):#测试成功
        ways = {
            "inter":"交互",
            "put_file":"传送文件",
            "get_file":"下载文件",
            "run_file":"操作文件",}#....通过调用help(key),阅读方法
        print(ways[arges[1]])
    def intersection(self):#"交互"功能;#输入指令,然后进行处理,传给其他函数...
       while True:
           msg = input(">>>:").strip()
           if len(msg) == 0:continue
           code = msg.split()
           act = code[0];file = code[1]
           if hasattr(self,act):
               fuc = getattr(self,act)
               fuc(act,file)#把操作和文件名 都 传进去
    def put(self,*args):#上传文件,传大小、黏包、发送文件
        if os.path.isfile(args[1]):
            print("调试")
            file_size = os.stat(args[1]).st_size
            print("文件大小",file_size)
            # self.client.send(file_size.encond("utf-8"))#传送size
            # self.client.send(args[1].encond("utf-8"))
            #优化一下,用json序列化去传
            msg = {
                "action":args[0],#传你要干什么
                "filname":args[1],#传名字
                "filsize":file_size,#传大小
                 }
            self.client.send(json.dumps(msg).encode("utf-8"))

        else:print("invailed fliname")
        self.client.recv(1024)#防止黏包
        f = open(args[1],"rb")
        #m = hashlib.md5
        for line in f :#send date
            self.client.send(line)
            #m.update(line);self.client.send(m.hexdigest)
        f.close()
        self.client.close()
    def get(self,*args):#下载文件
         msg = {
                "action":args[0],#传你要干什么
                "filname":args[1],#传文件名字
                 }
         self.client.send(json.dumps(msg).encode("utf-8"))

         total_size = self.client.recv(1024).decode()#1.接收大小
         self.client.send("i have get size....".encode("utf-8"))#2.黏包
         recevied_size = 0
         f = open(args[1],'wb')

         while recevied_size < int(total_size):
                if int(total_size) - recevied_size > 1024:
                    size = 1024
                else:size = int(total_size) - recevied_size
                date1 = self.client.recv(size)#接收date
                print(date1.decode())#调试
                recevied_size += len(date1)
                f.write(date1)
         else:f.close();self.client.close()

    def run(self,*args):#执行文件操作,调试成功(√)
        msg = {
                "action":args[0],#传你要干什么
                "filname":args[1],#传文件名字
                 }
        print(msg)
        self.client.send(json.dumps(msg).encode("utf-8"))

        total_size = self.client.recv(1024)#1.接收命令大小...
        print(total_size)#调试
        self.client.send("i am already...".encode("utf-8"))#黏包
        recevied_size = 0
        recevied_date = b''
        #一直接受这个指令...
        while recevied_size < int(total_size.decode()):
                if int(total_size.decode()) - recevied_size > 1024 :
                  size = 1024
                else:size  = int(total_size.decode()) - recevied_size

                data2 = self.client.recv(size)#循环收文件
                recevied_size += len(data2)#收的字节长度
                recevied_date += data2
        else:
                print(recevied_date.decode())#解码成字符串
                self.client.close()


client = FTP()
client.connect("localhost",9999)
client.intersection()

conclude:
1.def handle > while True > try…except…
2.基本的“熟记”

1.os.path.isfile();os.stat(filename).st_size
2.self.client.send(json.dumps(msg).encode(“utf-8”))

步骤多,调试很重要,还有就是这个在“连续操作”的时候,就会有OSError…大佬会的教我一下QAQ

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
/home/kejia/Server/tf/Bin_x64/DeepLearning/DL_Lib_02/torch/cuda/__init__.py:52: UserWarning: CUDA initialization: Unexpected error from cudaGetDeviceCount(). Did you run some cuda functions before calling NumCudaDevices() that might have already set an error? Error 803: system has unsupported display driver / cuda driver combination (Triggered internally at /pytorch/c10/cuda/CUDAFunctions.cpp:100.) return torch._C._cuda_getDeviceCount() > 0 gpu count 0 Traceback (most recent call last): File "DL_ProcessManager_01.py", line 5, in <module> File "<frozen importlib._bootstrap>", line 983, in _find_and_load File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 677, in _load_unlocked File "PyInstaller/loader/pyimod03_importers.py", line 540, in exec_module File "DL_ProcessManager/__init__.py", line 1, in <module> File "<frozen importlib._bootstrap>", line 983, in _find_and_load File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 677, in _load_unlocked File "PyInstaller/loader/pyimod03_importers.py", line 540, in exec_module File "DL_ProcessManager/DL_ProcessManager.py", line 12, in <module> File "/home/lxy/anaconda3/envs/mmdet2/lib/python3.7/site-packages/PyInstaller/hooks/rthooks/pyi_rth_multiprocessing.py", line 55, in _freeze_support File "multiprocessing/spawn.py", line 105, in spawn_main File "multiprocessing/spawn.py", line 115, in _main AttributeError: Can't get attribute 'CarmeraFunc' on <module '__main__' (built-in)> [15584] Failed to execute script DL_ProcessManager_01
最新发布
07-22

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值