基于TCP协议的socket实现文件的传输

一、 通过os 获取文件名的方法

程序示例:

import os
file_path = 'E:\java web\1000\wc.txt'

filename = os.path.basename(file_path)
print(filename)

执行结果:
在这里插入图片描述

二、实现小文件传输

比如要上传E:\java web\1000\wc.txt文件,如下:在这里插入图片描述

程序示例:

服务器端:
sever_.py

import socket
import json

sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()

conn,addr = sk.accept()


# 通信

str_dic = conn.recv(9090).decode('utf-8')
dic = json.loads(str_dic)
# dic = {'opt':menu.get(num),'filename':filename,'content':content}
if dic['opt'] == 'upload':
    # 上传
    filename = '0' + dic['filename'] # 新的文件名,为避免重名前面加个0
    with open(filename,'w',encoding='utf-8') as f:
        f.write(dic['content'])

conn.close()
sk.close()





客户端:
client_.py

import socket
import os
import json

sk = socket.socket()
sk.connect_ex(('127.0.0.1',8080))# 带返回值,如果出错,不会报错,会返回错误的编码
# sk.connect()# 会直接报错    两个都是连接服务器的功能

menu = {'1':'upload'}
for k,v in menu.items():
    print(k,v)

num = input('请输入操作代号【1】上传文件:')

if num == '1':
    # 上传功能
    # {你要执行的功能, 文件名, 文件内容}
    dic = {'opt':menu.get(num),'filename':None,'content':None}
    file_path = input('请输入一个文件的绝对路径>>>')
    #E:\java web\1000\wc.txt
    filename = os.path.basename(file_path)
    with open(file_path,'r',encoding='utf-8') as f:
        content = f.read()

    dic['filename'] = filename
    dic['content'] = content
    # print(dic)
    str_dic = json.dumps(dic)
    sk.send(str_dic.encode('utf-8'))



else:
    print('错误')


sk.close()

效果:
开启服务器端后,再开启客户端,输入绝对路径:E:\java web\1000\wc.txt
在这里插入图片描述

文件上传完成。

三、实现大文件传输

要上传的文件:
在这里插入图片描述

sever_.py

import socket
import json
sk = socket.socket()
sk.bind(("127.0.0.1",8001))
sk.listen()
conn,addr = sk.accept()
str_dic = conn.recv(100).decode("utf-8")
conn.send(b'ok')
# str_dic = {"opt":menu.get(num),"filename":None,"filesize":None}
dic = json.loads(str_dic)
if dic["opt"] == "upload":
    filename = "1"+ dic["filename"]
    with open(filename,"ab") as f:
        while dic['filesize']:
            content = conn.recv(1024)
            f.write(content)
            dic['filesize'] -= len(content)



conn.close()
sk.close()

client_.py

import socket
import os
import json
sk = socket.socket()
sk.connect(("127.0.0.1",8001))
menu = {"1":"upload"}
for k,v in menu.items():
    print(k,v)
num = input("请输入操作代号【1】上传文件:")
if num == "1":
    dic = {"opt":menu.get(num),"filename":None,"filesize":None}
    file_path = input("请输入一个绝对路径:")# 文件的绝对路径
    filename = os.path.basename(file_path)# 文件名字
    filesize = os.path.getsize(file_path)# 获取用户输入的路径中文件的大小
# E:\java web\2000\java web p1-p4 笔记.docx
    dic["filename"] = filename
    dic["filesize"] = filesize
    str_dic = json.dumps(dic)
    sk.send(str_dic.encode("utf-8"))# 将被填充完成的字典先发送给服务器
    sk.recv(1024)# 为什么要有一个recv?
    #  因为上边send字典时,如果程序执行过快,可能会马上执行到下边的send(content)
    #  此时有可能会发生粘包,所以在此中间加一个recv,为了避免粘包
    with open(file_path,"rb") as f:
        while filesize:
            content = f.read(1024)
            sk.send(content)
            filesize -= len(content)

效果:
在这里插入图片描述
上传成功。这里先卖个关子,后面讲粘包时会再对其进行优化。

读书能量分享

愿你自己有充分的忍耐去担当,有充分单纯的心去信仰;你将会越来越信任艰难的事物和你在众人中间感到的寂寞。
——里尔克《给一个青年诗人的十封信》 ​​​​

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰履踏青云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值