为了账号安全,请及时绑定邮箱和手机立即绑定

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))


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消