zoukankan      html  css  js  c++  java
  • FTP 作业整理

    一、FTP 客户端 与服务器端(没有解决黏包问题的代码)

    服务器端设置

    import socket
    import json
    ADDR = ('127.0.0.1',8081)
    sk =socket.socket()
    sk.bind(ADDR)
    sk.listen()
    conn,addr =sk.accept()
    
    content = conn.recv(1024).decode('utf-8') #接收文件的信息
    content_dic =json.loads(content) #将文件信息loads出来形成字典格式.
    print(content_dic,type(content_dic)) #打印查看一下loads的内容(字典)
    if content_dic['operate'] =='upload':
        conn.send(b'received!')
        with open(content_dic['file_name'],'wb') as f :#打开新建一个文件,名称和要上传的文件一样,以bytes类型的模式进行bytes类型写操作.
            while content_dic['file_size']:#循环,直到文件的大小为0
                file = conn.recv(1024) #接收文件每次以1024个byte的大小进行接收.
                f.write(file) #将接收到的文件写到创建的文件中
                content_dic['file_size']-=len(file)  #文件大小每次循环减
    conn.close()#关闭链接
    sk.close()#关闭 socket对象链接.

    客户端设置代码

    import socket
    import os
    import json
    
    sk=socket.socket()
    ADDR =('127.0.0.1',8081)
    sk.connect(ADDR)
    
    def get_filename(file_path):
        file_name =os.path.basename(file_path)
        return file_name
    
    operate =['upload','download']
    for num,opt in enumerate(operate,1):
        print(num,opt)
    
    num = int( input("请输入您要进行操作的序号:"))
    file_path = input('请输入要传的文件:')
    file_size = os.path.getsize(file_path)
    file_name =get_filename(file_path)
    
    if  num==1:#上传操作.
        dic ={ 'operate': 'upload','file_name':file_name, 'file_size':file_size}
        #创建一个字典包括了 操作,文件名,和文件大小.
        dic_str =json.dumps(dic)
        #将字典进行json操作转换成字符串.
        sk.send(dic_str.encode('utf-8'))
    #发送upload的字典信息,包括了文件名,路径和文件大小.

      第一次send(上面代码)
    
        sk.recv(1024)
    with open(file_path,
    'rb') as f :#打开想要上传的文件,以读的方式. while file_size:#(判断文件的大小是否非空,直到循环减为空) content = f.read(1024) #读出文件 1024个字节. sk.send(content) #将 1024个字节发送到服务器端. file_size-= len(content) #文件大小减到0 为止,停止循环.

      第二次send(上面的代码)

    运行结果

    二、FTP 上传加入黏包知识点

    借助struct模块,我们知道长度数字可以被转换成一个标准大小的4字节数字。因此可以利用这个特点来预先发送数据长度。

    发送时 接收时
    先发送struct转换好的数据长度4字节 先接受4个字节使用struct转换成数字来获取要接收的数据长度
    再发送数据 再按照长度接收数据

    服务器端设置

    import socket
    import json
    import struct
    ADDR = ('127.0.0.1',8081)
    sk =socket.socket()
    sk.bind(ADDR)
    sk.listen()
    conn,addr =sk.accept()
    len_4 = conn.recv(4)
    len_dic =struct.unpack('i',len_4)[0]#获取到内容的字节大小.
    content =conn.recv(len_dic).decode('utf-8')# 在接收内容大小.
    content_dic =json.loads(content) #将文件信息loads出来形成字典格式.
    
    print(content_dic,type(content_dic)) #打印查看一下loads的内容(字典)
    if content_dic['operate'] =='upload':
        conn.send(b'received!')
        with open(content_dic['file_name'],'wb') as f :#打开新建一个文件,名称和要上传的文件一样,以bytes类型的模式进行bytes类型写操作.
            while content_dic['file_size']:#循环,直到文件的大小为0
                file = conn.recv(1024) #接收文件每次以1024个byte的大小进行接收.
                f.write(file) #将接收到的文件写到创建的文件中
                content_dic['file_size']-=len(file)  #文件大小每次循环减
    conn.close()#关闭链接
    sk.close()#关闭 socket对象链

    客户端

    import socket
    import os
    import json
    import struct
    
    sk=socket.socket()
    ADDR =('127.0.0.1',8081)
    sk.connect(ADDR)
    
    def get_filename(file_path):
        file_name =os.path.basename(file_path)
        return file_name
    
    operate =['upload','download']
    for num,opt in enumerate(operate,1):
        print(num,opt)
    
    num = int( input("请输入您要进行操作的序号:"))
    file_path = input('请输入要传的文件:')
    file_size = os.path.getsize(file_path)
    file_name =get_filename(file_path)
    
    if  num==1:#上传操作.
        dic ={ 'operate': 'upload','file_name':file_name, 'file_size':file_size} #创建一个字典包括了 操作,文件名,和文件大小.
    
        dic_str =json.dumps(dic).encode('utf-8')    #将字典进行json操作转换成字符串.
    
        ret =struct.pack('i', len(dic_str))#将字典的大小转换成一个定长的4个字节的大小.
        sk.send(ret+dic_str) #将字典的大小和内容发送出去.
    
        with open(file_path,'rb') as f :#打开想要上传的文件,以读的方式.
             while file_size:#(判断文件的大小是否非空,直到循环减为空)
                content = f.read(1024) #读出文件 1024个字节.
                sk.send(content) #将 1024个字节发送到服务器端.
                file_size-= len(content) #文件大小减到0 为止,停止循环.
    
    sk.close()
    

    输出结果:

     

     

      

  • 相关阅读:
    BFC——块级格式化上下文
    深入浅出——float
    NodeJS 学习记录
    JavaScript高级程序设计 第六章 面向对象程序设计
    软件项目管理课感想
    第八周PSP 新折线图和饼图 个人时间管理
    第七周PSP 新折线图和饼图 个人时间管理
    Alpha、伪Beta 发布个人感想与体会
    ”单元测试“理解与感悟
    编程
  • 原文地址:https://www.cnblogs.com/mengbin0546/p/8666809.html
Copyright © 2011-2022 走看看