zoukankan      html  css  js  c++  java
  • socket传送文件

    一、文件传送步骤

      我们要利用socket来实现下载一个文件,该如何操作呢?

      服务端:

    1. 读取文件名
    2. 判断文件是否存在
    3. 检测文件大小(用于和客户端对比判断文件是否传送完毕)
    4. 发送文件大小给客户端
    5. 等待客户端确认(防止粘包)
    6. 打开文件
    7. 边读边发送数据
    8. md5验证

      客户端:

    • 发送命令
    • 接收文件大小
    • 返回确认
    • 获取文件名
    • 对比文件大小
    • 写入文件

    二、功能实现(ftp下载功能)

      服务端:

    # -*- coding: UTF-8 -*-
    import os
    import socket
    
    # TCP/IP协议, tcp ,如果不填写就是默认这个
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    server.bind(('localhost', 9999))
    
    server.listen()
    
    while True:  # 可以接受多个客户端
    
        conn, addr = server.accept()
        print('new conn', addr)
        while True:
    
            cmd_res = conn.recv(1024)
            if not cmd_res:   # 防止当接受的客户端数据为空时,程序卡掉
                print('client has lost...')
                break
            else:
                # 获取命令和文件名
                cmd, filename = cmd_res.decode().split()
                print(cmd, filename)
                if os.path.isfile(filename):  # 判断文件是否存在
                    # 文件大小
                    file_size = os.stat(filename).st_size
                    # 发送文件大小
                    conn.send(str(file_size).encode(encoding='utf-8'))
                    # 等待客户端确认
                    conn.recv(1024)
                    # 打开文件
                    f = open(filename, 'rb')
                    for line in f:
                        conn.send(line)
                        print('sending')
                    f.close()
    View Code

      客户端:

    # -*- coding: UTF-8 -*-
    import socket
    
    client = socket.socket()
    
    client.connect(('localhost', 9999))
    
    while True:
        cmd = input('>>:').strip()
        # 判断是否发送空数据,如果是就重新发送
        if len(cmd) == 0:
            continue
        else:
            client.send(cmd.encode('utf-8'))
            # 获取服务端发送的文件大小
            size = client.recv(1024)
            total_file_size = int(size.decode())
    
            # 返回确认
            client.send(b'file size received')
            filename = cmd.split()[1]
            print(filename)
            received_size = 0
            # 写入文件
            f = open(filename + '.new', 'w', encoding='utf-8')
            while received_size < total_file_size:
                r_data = client.recv(1024)
                received_size += len(r_data)
                f.write(r_data.decode() + '
    ')
            else:
                print('file sizes', total_file_size, received_size)
                print('receive finished')
                f.close()
    View Code

     有些问题 替换一些内容  

    f = open(filename + '.new', 'wb')
    f.write(r_data)

       

      这个程序有缺陷,首先目前只能读取本文件夹下的文件,新生成的文件没有中文乱码问题,ok...

    三、md5验证文件

      加个md5来验证文件是否一致

      服务端:

    # -*- coding: UTF-8 -*-
    import os
    import socket
    import hashlib
    
    # TCP/IP协议, tcp ,如果不填写就是默认这个
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    server.bind(('localhost', 9999))
    
    server.listen()
    
    while True:  # 可以接受多个客户端
    
        conn, addr = server.accept()
        print('new conn', addr)
        while True:
    
            cmd_res = conn.recv(1024)
            if not cmd_res:   # 防止当接受的客户端数据为空时,程序卡掉
                print('client has lost...')
                break
            else:
                # md5
                m = hashlib.md5()
                # 获取命令和文件名
                cmd, filename = cmd_res.decode().split()
                print(cmd, filename)
                if os.path.isfile(filename):  # 判断文件是否存在
                    # 文件大小
                    file_size = os.stat(filename).st_size
                    print(file_size)
                    # 发送文件大小
                    conn.send(str(file_size).encode(encoding='utf-8'))
                    # 等待客户端确认
                    conn.recv(1024)
                    # 打开文件
                    f = open(filename, 'rb')
                    for line in f:
                        m.update(line)
                        # m.update('abc')  m.update('123')
                        # 其实和m.update('abc123') 结果一下
                        conn.send(line)
    
                    f.close()
                    print('send done')
                    # 发送md5信息
                    conn.send(m.hexdigest().encode('utf-8'))
    

      客户端:

    # -*- coding: UTF-8 -*-
    import socket
    import hashlib
    
    client = socket.socket()
    
    client.connect(('localhost', 9999))
    
    while True:
        cmd = input('>>:').strip()
        # 判断是否发送空数据,如果是就重新发送
        if len(cmd) == 0:
            continue
        else:
            client.send(cmd.encode('utf-8'))
            # 获取服务端发送的文件大小
            f_size = client.recv(1024)
            total_file_size = int(f_size.decode())
    
            # 返回确认
            client.send(b'file size received')
            filename = cmd.split()[1]
            print(filename)
            received_size = 0
            # md5
            m = hashlib.md5()
    
            # 写入文件
            f = open(filename + '.new', 'wb')  # 新生成的文件也正常显示
            while received_size < total_file_size:
                if total_file_size - received_size > 1024:  # 以此来控制只收文件的内容,不会粘包md5的内容
                    size = 1024
                else:
                    size = total_file_size - received_size
                r_data = client.recv(size)
                received_size += len(r_data)
                m.update(r_data)
                f.write(r_data)
                # print(r_data.decode())
                # print('file sizes', total_file_size, received_size)
            else:
                print('file sizes', total_file_size, received_size)
                server_md5 = client.recv(1024).decode()
                client_md5 = m.hexdigest()
                print(server_md5)
                print(client_md5)
                print('receive finished')
                f.close()
    

      结果:

      

      结果看上去没有问题了,新文件也能生成,并且有内容

  • 相关阅读:
    WPF 重新启动该程序
    Winform水印
    PS 切HTML (ps+div+css)
    VS服务器运行有问题 怎么办?
    ISDeleted 软删除!!
    项目初始框架
    MD5加密
    !!LoginWindow.cs
    !!!精简版三层架构
    !!C#交互操作SqlServer数据库 基本的增删改查
  • 原文地址:https://www.cnblogs.com/bigberg/p/7750182.html
Copyright © 2011-2022 走看看