需求:一个server,一个client,实现client把某个文件传到server中某个目录中

分析:实际是实现数据传输,设定一个命令和一个参数(上传的内容),连接后,让用户输入命令和要传送的内容,如post 2.png,先解析这个命令,找到2.png发送到server端,命令格式自定义

1. server,client基本连接框架
[root@node2 file_upload]# cat post_server.py
#!/usr/local/python3/bin/python3
import socket
import subprocess
sk = socket.socket()
address=('127.0.0.1',8888)
sk.bind(address)
sk.listen(3)
print('waiting...')
while True:
conn, addr = sk.accept()
while True:
sk.close()
inp需要有用户输入
[root@node2 file_upload]# cat post_client.py
#!/usr/local/python3/bin/python3
import socket
import os
sk=socket.socket()
address=('127.0.0.1',8888)
sk.connect(address)
while True:
inp=input('>>> ') # post | path
sk.close()

2.建立连接后,post_client.py先发起动作,制定上传命令的格式post|2.png,通过|来分隔查找

a.需要一个base_dir,因为并不知道路径在那里,只知道在当前路径下,client.py的上一层就file_upload目录,再加2.png就可以,使用BASE_DIR与2.png这个内容(相对路径)进行拼接就可以了

BASE_DIR=os.path.dirname(os.path.abspath(__file__))

b.解析命令

cmd,path=inp.split('|')

c.拼接路径,使用join都可以使用相关平台的默认方式拼接(linux/windows),同时赋变量path

path=os.path.join(BASE_DIR,path)

d.需要文件的名字,2.png是一个名字,但是也可以在某个目录下,如post|reid/2.png,要与base_dir拼接才是一个绝对路径,filename是要让服务器知道它重新写的文件的名称,server与client的文件名要统一,所以要把名称通知server端

filename=os.path.basename(path) #参数是路径,可以取到文件名字

e.需要文件大小,通知server要接收文件的大小

file_size=os.stat(path).st_size

f.把内容打成一个包传输过去,还可以实现把文件存储在那个位置,没有可以创建目录,命令post,再加相应的内容,server端接收这种信息后,进行解释

file_info='post|%s|%s'%(filename,file_size)
g.把数据包传送到server
sk.sendall(bytes(file_info,'utf8'))
3. post_server到post_client内容进行接收
a. 接收数据
data=conn.recv(1024)
b.对数据解释,分配三个变量来解释
cmd,filename,filesze=str(data,'utf8').split('|')
c.加入相应的BASE_DIR,拼接路径
import os
BASE_DIR=os.path.dirname(os.path.abspath(__file__))
while True:
conn, addr = sk.accept()
while True:
data=conn.recv(1024)
cmd,filename,filesze=str(data,'utf8').split('|')
path=os.path.join(BASE_DIR,'storage',filename)
######storage已经固定,可以传过来后再拼接,BASE_DIR是当前文件的上级,storage同一路径的目录,filename文件名
d.把字符串类型的filesize转换成int类型
filesze=int(filesze)
4.post_client开始发送数据
a.打开文件,rb以bytes类型读,不加是以字符串的类型读
f=open(path,'rb')
b.读取文件,read是全部读取的,定义一次1024字节大小,发送一段段的发
data=f.read(1024)
c.判断什么时候把数据发完
has_sent=0 #初始化发送的大小,has_sent已经发过去的内容,不能设置bytes
while has_sent!=file_size: #filez_size是int类型,has_sent也是
data=f.read(1024) #读数据
sk.sendall(data) #发送到server
has_sent+=len(data) #累加的是data的长度,has_sent是一个int整型,如果累加1024就要是它的倍数,有可能不是
f.close()
print('upload success')
5.post_server进行接收数据
a.打开文件
f=open(path,'ab')
b.循环接收
has_received=0
while has_received!=filesze:
data=conn.recv(1024) #data是bytes类型
f.write(data) #直接写
has_received+=len(data)
f.close()
6.完整代码
[root@node2 file_upload]# cat post_client.py
1 #!/usr/local/python3/bin/python32 import socket3 import os4 sk=socket.socket()5 address=('127.0.0.1',8888)6 sk.connect(address)7
8 BASE_DIR=os.path.dirname(os.path.abspath(__file__))9
10 whileTrue:11 inp=input('>>>').strip() # post |path12 cmd,path=inp.split('|')13 path=os.path.join(BASE_DIR,path)14 filename=os.path.basename(path)15 file_size=os.stat(path).st_size16 file_info='post|%s|%s'%(filename,file_size)17 sk.sendall(bytes(file_info,'utf8'))18
19 f=open(path,'rb')20 data=f.read(1024)21
22 has_sent=0
23 while has_sent!=file_size:24 data=f.read(1024)25 sk.sendall(data)26 has_sent+=len(data)27 f.close()28 print('upload success')29
30 sk.close()
View Code
[root@node2 file_upload]# cat post_server.py
1 #!/usr/local/python3/bin/python32 import socket3 import subprocess4 import os5 # family type6 sk =socket.socket()7 address=('127.0.0.1',8888)8 sk.bind(address)9 sk.listen(3)10 BASE_DIR=os.path.dirname(os.path.abspath(__file__))11
12 whileTrue:13 conn, addr =sk.accept()14 whileTrue:15 data=conn.recv(1024)16 cmd,filename,filesze=str(data,'utf8').split('|')17 path=os.path.join(BASE_DIR,'file_upload',filename)18 filesze=int(filesze)19
20 f=open(path,'ab')21 has_received=0
22 while has_received!=filesze:23 data=conn.recv(1024)24 f.write(data)25 has_received+=len(data)26 f.close()27
28 sk.close()
View Code
7.测试
[root@node2 file_upload]# python3 post_server.py
waiting...
[root@node2 file_upload]# python3 post_client.py
>>> post|2.png
[root@node2 py]# tree file_upload/
file_upload/
├── 2.png
├── post_client.py
├── post_server.py
└── storage
└── 2.png