• Python3利用socket处理文件的传输问题


        记录瞬间    

    最近处理相关的事情时,遇到了需要使用传输文件的方法,网上尽管一搜一大堆,但是还是有一些复杂,最后找到一篇比较简单直接的方法

    但是有效果就是好方法

    特意记录如下:

    Python代码  服务端

    import socket,struct
    host = '0.0.0.0'
    port = 3000
    fmt = '128si' #文件名最长128 i表示文件大小 i的数据类型决定了最大能够传输多大的文件 
    recv_buffer = 4096
    listenSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    listenSock.bind((host, port))
    while True:
        listenSock.listen(5)
        conn, addr = listenSock.accept()
        headsize = struct.calcsize(fmt)
        head = conn.recv(headsize)
        filename = struct.unpack(fmt, head)[0].decode().rstrip('') #要删掉用来补齐128个字节的空字符
        filename = '/tmp/'+filename 
        filesize = struct.unpack(fmt, head)[1]
        print("filename:" + filename + "
    filesize:" + str(filesize))
        recved_size = 0
        fd = open(filename, 'wb')
        count = 0
        while True:
            data = conn.recv(recv_buffer)
            recved_size = recved_size + len(data) #虽然buffer大小是4096,但不一定能收满4096
            fd.write(data)
            if recved_size == filesize:
                break
        fd.close()
        print("new file")
    

      

    Python代码  客户端

    import socket, os, struct
     
    host = '接收端IP'
    port = 3000
    fmt = '128si'
    send_buffer = 4096
     
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((host, port))
    filepath = input("enter file path:")
    filename = os.path.split(filepath)[1]
    filesize = os.path.getsize(filepath)
    print("filename:" + filename + "
    filesize:" + str(filesize))
    head = struct.pack(fmt, filename.encode(), filesize)
    print("
    head size:" + str(head.__len__()) + "
    " + str(head))
    sock.sendall(head)
    restSize = filesize
    fd = open(filepath,'rb')
    count = 0
    while restSize >= send_buffer:
        data = fd.read(send_buffer)
        sock.sendall(data)
        restSize = restSize - send_buffer
        print(str(count)+" ")
        count = count + 1
    data = fd.read(restSize)
    sock.sendall(data)
    fd.close()
    print("successfully sent")
    

      

    其中要注意替换客户端中的ip地址信息

    关键的思路是:

    1、先要对包的信息(这里是文件名和大小)使用struct模块将其转化为二进制串发送给接收方

    2、接收方d根据包信息进行接收

    需要注意的是:

    1、在不同操作系统下 fmt格式中的数据类型大小可能不同,因此可能会出现两边计算出的headsize不同的情况

    2、没有进行异常处理

    亲测可用。

    ++++++++++++++我只是底线++++++++++++++

  • 相关阅读:
    磁盘IO工作机制
    java 的IO类库的基本架构
    诡异的NPE--三目运算自动类型转换
    WIN2008服务器不能复制粘贴怎么办
    用nrm一键切换npm源
    Linux常用命令大全(非常全!!!)
    整理 node-sass 安装失败的原因及解决办法
    win10完美去除小箭头
    JS中slice,splice,split的区别
    Win10环境下Redis和Redis desktop manager 安装
  • 原文地址:https://www.cnblogs.com/wozijisun/p/13730337.html
Copyright © 2020-2023  润新知