服务端
import socket
import argparse
import struct
import json
import os
def recvall(sock, length):
data = b''
while len(data) < length:
more = sock.recv(length - len(data))
if not more:
raise Exception("peer closed.")
data += more
return data
def handle_dir_req(csock, req):
# 1.获得文件清单
res = os.listdir()
res_bytes = json.dumps(res).encode()
# 2.构造响应头
head = {
'status': 'ok',
'content-length': len(res_bytes),
}
head_bytes = json.dumps(head).encode()
# 3.构造响应头长度信息
head_length = len(head_bytes)
head_length_bytes = struct.pack('>i', head_length)
# 4.发送3段数据
csock.sendall(head_length_bytes)
csock.sendall(head_bytes)
csock.sendall(res_bytes)
def handle_get_req(csock, file):
# res=os.read(req)
# res_bytes = json.dumps(res).encode()
res_bytes = open(file,"rb").read()
# 2.构造响应头
head = {
'status': 'ok',
'content-length': len(res_bytes),
'file':file,
}
head_bytes = json.dumps(head).encode()
head_length = len(head_bytes)
head_length_bytes = struct.pack('>i', head_length)
csock.sendall(head_length_bytes)
csock.sendall(head_bytes)
csock.sendall(res_bytes)
def handle_up_req(csock,res_head):
res_data_length = res_head["content-length"]
res_data_bytes = recvall(csock, res_data_length)
open(res_head['name'], 'wb').write(res_data_bytes)
# 2.构造响应头
res='success!',
res_bytes=json.dumps(res).encode()
head = {
'status': 'ok',
'content-length': len(res_bytes),
}
head_bytes = json.dumps(head).encode()
head_length = len(head_bytes)
head_length_bytes = struct.pack('>i', head_length)
csock.sendall(head_length_bytes)
csock.sendall(head_bytes)
csock.sendall(res_bytes)
def handle_dele_req(csock,req):
os.remove(req)
res = 'success!',
res_bytes = json.dumps(res).encode()
head = {
'status': 'ok',
'content-length': len(res_bytes),
}
head_bytes = json.dumps(head).encode()
head_length = len(head_bytes)
head_length_bytes = struct.pack('>i', head_length)
csock.sendall(head_length_bytes)
csock.sendall(head_bytes)
csock.sendall(res_bytes)
def handel_exit_req(csock,req):
name='success!'
res_bytes = json.dumps(name).encode()
# 2.构造响应头
head = {
'status': 'ok',
'content-length': len(res_bytes),
}
head_bytes = json.dumps(head).encode()
head_length = len(head_bytes)
head_length_bytes = struct.pack('>i', head_length)
csock.sendall(head_length_bytes)
csock.sendall(head_bytes)
csock.sendall(res_bytes)
mapping = {
"dir": handle_dir_req,
"get": handle_get_req,
"upload": handle_up_req,
"dele": handle_dele_req,
"exit": handel_exit_req,
}
def serve_ftp_client(csock):
while True:
try:
# 1.获得请求头,然后解析json格式,判断是get还是dir
head_length_bytes = recvall(csock, 4)
head_length = struct.unpack('>i', head_length_bytes)[0]
req_bytes = recvall(csock, head_length)
req = json.loads(req_bytes.decode())
# 2.根据客户的请求去调用具体的子函数
cmd = req.get("cmd")
name=req.get("name")
print(req)
if cmd =='upload':
handle_up_req(csock, req)
else:
function = mapping[cmd]
function(csock, name)
except Exception as e:
break
def main(ip='0.0.0.0', port=21):
# 1. 创建socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. bind
sock.bind((ip, port))
# 3. listen
sock.listen(1)
# 4. 进入循环accept
while True:
csock, caddr = sock.accept()
# 5. 服务客户send/recv
serve_ftp_client(csock)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="ftp server v0.1")
parser.add_argument("--ip", default='0.0.0.0', help="ftp server ip, default=0.0.0.0")
parser.add_argument("--port", type=int, default=21, help="ftp server port, default=21")
args = parser.parse_args()
main(args.ip, args.port)
客户端
# coding:utf8
import argparse
import json
import socket
import struct
def recvall(sock, length):
data = b''
while len(data) < length:
more = sock.recv(length - len(data))
if not more:
raise Exception("peer closed.")
data += more
return data
def recv_responsed(sock):
head_length_bytes = recvall(sock, 4)
head_length = struct.unpack('>i', head_length_bytes)[0]
req_head_bytes = recvall(sock, head_length)
res_head = json.loads(req_head_bytes.decode())
res_data_length = res_head["content-length"]
res_data_bytes = recvall(sock, res_data_length)
res = json.loads(res_data_bytes.decode())
return res
def recv_response(sock):
head_length_bytes = recvall(sock, 4)
head_length = struct.unpack('>i', head_length_bytes)[0]
req_head_bytes = recvall(sock, head_length)
res_head = json.loads(req_head_bytes.decode())
res_data_length = res_head["content-length"]
res_data_bytes = recvall(sock, res_data_length)
open(res_head['file'],'wb').write(res_data_bytes)
return 'success!'
def main(ip, port):
# 1. 创建socket
csock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. connect
csock.connect((ip, port))
# 3. input/send/recv
while True:
cmd = input("请输入您的命令(例:dir,get,upload,dele,exit):").strip()
if cmd == 'dir':
head = {'cmd': 'dir'}
head_bytes = json.dumps(head).encode()
head_length = len(head_bytes)
head_length_bytes = struct.pack('>i', head_length)
csock.sendall(head_length_bytes)
csock.sendall(head_bytes)
res = recv_responsed(csock)
print(res)
elif cmd == 'get':
name= input("请输入文件名:").strip()
head = {'cmd': 'get','name':name}
head_bytes = json.dumps(head).encode()
head_length = len(head_bytes)
head_length_bytes = struct.pack('>i', head_length)
csock.sendall(head_length_bytes)
csock.sendall(head_bytes)
res = recv_response(csock)
print(res)
elif cmd =='upload':
file= input("请输入文件名:").strip()
#res = os.stat(file)
res_bytes = open(file, "rb").read()
head = {
'cmd':'upload',
'status': 'ok',
'content-length': len(res_bytes),
'name': file,
}
head_bytes = json.dumps(head).encode()
head_length = len(head_bytes)
head_length_bytes = struct.pack('>i', head_length)
csock.sendall(head_length_bytes)
csock.sendall(head_bytes)
csock.sendall(res_bytes)
res = recv_responsed(csock)
print(res)
elif cmd == 'dele':
name = input("请输入文件名:").strip()
head = {'cmd': 'dele', 'name': name}
head_bytes = json.dumps(head).encode()
head_length = len(head_bytes)
head_length_bytes = struct.pack('>i', head_length)
csock.sendall(head_length_bytes)
csock.sendall(head_bytes)
res = recv_responsed(csock)
print(res)
elif cmd == 'exit':
break
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="ftp client v0.1")
parser.add_argument("--ip", default='127.0.0.1', help="ftp server ip, default=127.0.0.1")
parser.add_argument("--port", type=int, default=21, help="ftp server port, default=21")
args = parser.parse_args()
main(args.ip, args.port)