Python语言 tcp socket 传送文件
小标 2018-12-10 来源 : 阅读 1279 评论 0

摘要:本文主要向大家介绍了Python语言 tcp socket 传送文件,通过具体的内容向大家展示,希望对大家学习Python语言有所帮助。

本文主要向大家介绍了Python语言 tcp socket 传送文件,通过具体的内容向大家展示,希望对大家学习Python语言有所帮助。

【测试环境】os:Windows 10 x64
Python:3.6.3【server.py】#encoding: utf-8
#author: walker
#date:  2017-12-01 
#summary: 用socket创建tcp server以接收文件 
 
import os, time
import socket
import struct
 
cur_dir_fullpath = os.path.dirname(os.path.abspath(__file__))
 
Host = '127.0.0.1'
Port = 6789
BufSize = 8196
FmtHead = '256sHL'    #L决定单个文件必须小于4G
FmtHeadLen = struct.calcsize(FmtHead)
DstRoot = os.path.join(cur_dir_fullpath, 'output')   #目标目录
StartTime = time.time()       #开始时间  
     
def ProcAll():
        cnt = 0
        fileSizeTotal = 0
        sockServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sockServer.bind((Host, Port))
        print('Listen prot %d ...' % Port)
        sockServer.listen(1)
        sock, addr = sockServer.accept()
        print('local: %s:%d' % (sock.getsockname()))
        print('client: %s:%d' % addr)
        while True:
            #接收数据包头(相对路径,相对路径长度,文件大小)
            pkgHead = sock.recv(FmtHeadLen)
            relPath, relPathLen, fileSize = struct.unpack(FmtHead, pkgHead)
            relPath = relPath.decode('utf8')[0:relPathLen]
            if relPath == 'OVER' and fileSize == 0:
                print('All file recv over!')
                break
            pathfile = os.path.join(DstRoot, relPath)
            dstDir = os.path.dirname(pathfile)
            if not os.path.exists(dstDir):
                os.makedirs(dstDir)
            with open(pathfile, mode='wb') as f:
                recvSize = 0  #单文件已接收字节数
                while True:
                    if recvSize >= fileSize:
                        break
                    bufSize = BufSize
                    if fileSize - recvSize < BufSize:   #剩余字节数小于BufSize
                        bufSize = fileSize - recvSize
                    buf = sock.recv(bufSize)
                    f.write(buf)
                    recvSize += len(buf)
                fileSizeTotal += recvSize
            cnt += 1
            print('cnt: %d, time cost: %.2fs, %s'% (cnt, time.time()-StartTime, pathfile))
                     
        sock.close()
        sockServer.close()
         
        print('cnt: %d, time total: %.2fs, send bytes:%ld B'% (cnt, time.time()-StartTime, fileSizeTotal))
 
if __name__ == '__main__':
    ProcAll()
     
    print('Time total:%.2fs' % (time.time() - StartTime))【client.py】#encoding: utf-8
#author: walker
#date: 2017-12-01 
#summary: 用socket连接tcp server以传送文件
 
import os, time
import socket
import struct
 
cur_dir_fullpath = os.path.dirname(os.path.abspath(__file__))
 
Host = '127.0.0.1'
Port = 6789
BufSize = 8196
FmtHead = '256sHL'    #L决定单个文件必须小于4G
SrcRoot = os.path.join(cur_dir_fullpath, 'input')    #源目录
ExtSet = {'.pdf', '.html', '.htm'}      #后缀列表
StartTime = time.time()       #开始时间
 
 
def ProcAll():
    cnt = 0
    fileSizeTotal = 0
    sockClient = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print('Connect %s:%d ...' % (Host, Port))
    sockClient.connect((Host, Port))
    print('local: %s:%d' % (sockClient.getsockname()))
    for parent, dirnames, filenames in os.walk(SrcRoot):
        for filename in filenames:
            if os.path.splitext(filename)[1].lower() not in ExtSet: #排除非指定后缀的文件
                continue
            pathfile = os.path.join(parent, filename)
            relPath = pathfile[len(SrcRoot):].strip(os.path.sep)  #相对路径(相对于SrcRoot)
            fileSize = os.path.getsize(pathfile)
            #发送数据包头(相对路径,相对路径长度,文件大小)
            pkgHead = struct.pack(FmtHead, relPath.encode('utf8'), len(relPath), fileSize)
            sockClient.sendall(pkgHead)
            with open(pathfile, mode='rb') as f:
                while True:
                    buf = f.read(BufSize)
                    if len(buf) < 1:
                        break
                    sockClient.sendall(buf)
            fileSizeTotal += fileSize
            cnt += 1
            print('cnt: %d, time cost: %.2fs, %s'% (cnt, time.time()-StartTime, pathfile))
     
    #发送文件传送结束消息
    pkgHead = struct.pack(FmtHead, 'OVER'.encode('utf8'), len('OVER'), 0)
    sockClient.sendall(pkgHead)
     
    sockClient.close()
     
    print('cnt: %d, time total: %.2fs, send bytes:%ld B'% (cnt, time.time()-StartTime, fileSizeTotal))
     
 
if __name__ == '__main__':
     
     
    ProcAll()
     
    print('Time total:%.2fs' % (time.time() - StartTime))    

本文由职坐标整理并发布,希望对同学们学习Python有所帮助,更多内容请关注职坐标编程语言Python频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程