FTP项目
查看列表
客户端
from socket import *
import pickle
def list_file():
# 3.创建对象
tcp_client = socket()
# 4.连接服务器
tcp_client.connect(("172.16.13.212", 8989))
# 5.发送消息
tcp_client.send("L".encode("utf-8"))
# 6.接收消息
raw_data = tcp_client.recv(1024)
# 7.转化消息类型
data = pickle.loads(raw_data)
# 8.展示消息内容
print(data)
# 关闭连接
# tcp_client.close()
def down_file():
pass
def upload_file():
pass
def main():
while True:
# 1.提示输入操作命令
print("L:查看列表\nD:下载\nU:上传\nexit:退出")
data = input(">>>请选择命令:")
# 2.判断用户的功能
if data == "exit":
# 2.0退出
break
elif data[0].upper().strip() == "L":
# 2.1查看列表
list_file()
elif data[0].upper().strip() == "D":
# 2.2下载
down_file()
elif data[0].upper().strip() == "U":
# 2.3上传
upload_file()
else:
print("命令错误,请重新输入")
if __name__ == '__main__':
main()
客户端
from socket import *
import os
import pickle
def list_file(sock):
print("查看列表")
# a.查看当前目录,生成列表
data = os.listdir()
# b.对列表进行序列化
data = pickle.dumps(data)
# c.返回消息
res = sock.send(data)
print(f"成功发送{res}字节")
# d.断开连接
sock.close()
def down_file(sock):
pass
def upload_file(sock):
pass
def main():
# 1.创建对象
tcp_server = socket()
# 2.保证端口不被占用
tcp_server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
# 3.绑定端口
tcp_server.bind(("", 8989))
# 4.改主动为被动 注:只有在unix下生效
tcp_server.listen(5)
# 5.等待连接
while True:
# 6.解包
new_socket, client_info = tcp_server.accept()
# 7.接收消息
raw_data = new_socket.recv(1024)
# 8.判断客户有没有断开
if raw_data:
# 9.判断客户的命令
if raw_data.decode("utf-8")[0] == "L":
# 9.1查看文件列表
list_file(new_socket)
if raw_data.decode("utf-8")[0] == "L":
# 9.2下载
down_file(new_socket)
if raw_data.decode("utf-8")[0] == "L":
# 9.3上传
upload_file(new_socket)
else:
# 10.关闭
new_socket.close()
break
if __name__ == '__main__':
main()
下载
遇坑:linux下为服务端,在windows连接不上虚拟机的服务端
解决办法:在linux下运行命令 service iptables stop 关闭了linux防火墙
客户端
from socket import *
import pickle
def list_file():
# 3.创建对象
tcp_client = socket()
# 4.连接服务器
tcp_client.connect(("192.168.2.107", 8989))
# 5.发送消息
tcp_client.send("L".encode("utf-8"))
# 6.接收消息
raw_data = tcp_client.recv(1024)
# 7.反序列化
data = pickle.loads(raw_data)
# 8.展示消息内容
print(data)
# 关闭连接
# tcp_client.close()
def down_file(data):
# 3.创建对象
tcp_client = socket()
# 4.连接服务器
tcp_client.connect(("192.168.2.107", 8989))
# 5.获取到文件名
file_name = data[2:]
# 6.发送消息
tcp_client.send(f"D:{file_name}".encode("utf-8"))
# 7.接收消息
raw_data = tcp_client.recv(1024)
# 8.打开新文件保存消息
with open(file_name, "ab") as fw:
# 9判断是否接收到消息
while raw_data:
# 10.保存到文件中
fw.write(raw_data)
# 11.继续接收消息
raw_data = tcp_client.recv(1024)
# 12.关闭连接
# tcp_client.close()
def upload_file():
pass
def main():
while True:
# 1.提示输入操作命令
print("=" * 30, "\nL:查看列表\nD:下载\nU:上传\nexit:退出\n", "=" * 30)
data = input(">>>请选择命令:")
# 2.判断用户的功能
if data == "exit":
# 2.0退出
break
elif data[0].upper().strip() == "L":
# 2.1查看列表
list_file()
elif data[0].upper().strip() == "D":
# 2.2下载
down_file(data)
elif data[0].upper().strip() == "U":
# 2.3上传
upload_file()
else:
print("命令错误,请重新输入")
if __name__ == '__main__':
main()
服务端
from socket import *
import os
import pickle
def list_file(sock):
print("查看列表")
# 11.查看当前目录,生成列表
data = os.listdir()
# 12.对列表进行序列化
data = pickle.dumps(data)
# 13.返回消息
res = sock.send(data)
print(f"成功发送{res}字节")
# 14.断开连接
sock.close()
def down_file(sock, data):
print("下载")
# 11.获取文件名
file_name = data.decode("utf-8")[2:]
# 12.发送文件内容
# 13.打开文件
with open(file_name, "rb") as fr:
# 14.一次获取1024
buf = fr.read(1024)
# 15.判断是否取到消息
while buf:
# 16.把取到的写入到文件中
sock.send(buf)
# 17.继续从缓存区取
buf = fr.read(1024)
# 18.关闭文件
fr.close()
# 19.关闭连接
sock.close()
def upload_file(sock):
pass
def main():
# 1.创建对象
tcp_server = socket()
# 2.保证端口不被占用
tcp_server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
# 3.绑定端口
tcp_server.bind(("", 8989))
# 4.改主动为被动 注:只有在unix下生效
tcp_server.listen(5)
# 5.等待连接
while True:
# 6.解包
new_socket, client_info = tcp_server.accept()
# 7.接收消息
raw_data = new_socket.recv(1024)
# 8.判断客户有没有断开
if raw_data:
# 9.判断客户的命令
if raw_data.decode("utf-8")[0] == "L":
# 9.1查看文件列表
list_file(new_socket)
if raw_data.decode("utf-8")[0] == "D":
# 9.2下载
down_file(new_socket, raw_data)
if raw_data.decode("utf-8")[0] == "U":
# 9.3上传
upload_file(new_socket)
else:
# 10.关闭
new_socket.close()
break
if __name__ == '__main__':
main()
上传
遇坑:粘包
解决办法:在文件名前传递了文件名长度
注意:文件名最大长度255
客户端
from socket import *
import pickle
def list_file():
# 3.创建对象
tcp_client = socket()
# 4.连接服务器
tcp_client.connect(("192.168.2.107", 8989))
# 5.发送消息
tcp_client.send("L".encode("utf-8"))
# 6.接收消息
raw_data = tcp_client.recv(1024)
# 7.反序列化
data = pickle.loads(raw_data)
# 8.展示消息内容
print(data)
# 9.关闭连接
tcp_client.close()
def down_file(data):
# 3.创建对象
tcp_client = socket()
# 4.连接服务器
tcp_client.connect(("192.168.2.107", 8989))
# 5.获取到文件名
file_name = data[2:]
# 6.发送消息
tcp_client.send(f"D:{file_name}".encode("utf-8"))
# 7.接收消息
raw_data = tcp_client.recv(1024)
# 8.打开新文件保存消息
with open(file_name, "ab") as fw:
# 9判断是否接收到消息
while raw_data:
# 10.保存到文件中
fw.write(raw_data)
# 11.继续接收消息
raw_data = tcp_client.recv(1024)
# 12.关闭连接
tcp_client.close()
def upload_file(data):
# 3.创建对象
tcp_client = socket()
# 4.连接服务器
# tcp_client.connect(("192.168.2.107", 8989))
# tcp_client.connect(("192.168.2.104", 8989))
tcp_client.connect(("172.16.13.216", 8988))
# 5.获取到文件名
file_name = data[2:].strip()
# 6.获取到文件名的长度,并转化为3位数的字符串,左边补0
length = "%05d" % len(file_name.encode("utf-8"))
# 6.发送消息
tcp_client.send(f"U:{length}{file_name}".encode("utf-8"))
# 7.打开文件
with open(file_name, "rb") as fr:
# 8.一次取1024
buf = fr.read(1024)
# 9.如果取出内容
while buf:
# 10.把取出的文件发给服务器
tcp_client.send(buf)
# 11.继续获取
buf = fr.read(1024)
# 12.关闭连接
tcp_client.close()
def main():
while True:
# 1.提示输入操作命令
print("=" * 30, "\nL:查看列表\nD:下载\nU:上传\nexit:退出\n", "=" * 30)
data = input(">>>请选择命令:")
# 2.判断用户的功能
if data == "exit":
# 2.0退出
break
elif data[0].upper().strip() == "L":
# 2.1查看列表
list_file()
elif data[0].upper().strip() == "D":
# 2.2下载
down_file(data)
elif data[0].upper().strip() == "U":
# 2.3上传
upload_file(data)
else:
print("命令错误,请重新输入")
if __name__ == '__main__':
main()
服务端
from socket import *
import os
import pickle
def list_file(sock):
print("查看列表")
# 11.查看当前目录,生成列表
data = os.listdir()
# 12.对列表进行序列化
data = pickle.dumps(data)
# 13.返回消息
res = sock.send(data)
print(f"成功发送{res}字节")
# 14.断开连接
sock.close()
def down_file(sock, data):
print("下载")
# 11.获取文件名
file_name = data.decode("utf-8")[2:]
# 12.发送文件内容
# 13.打开文件
with open(file_name, "rb") as fr:
# 14.一次获取1024
buf = fr.read(1024)
# 15.判断是否取到消息
while buf:
# 16.把取到的写入到文件中
sock.send(buf)
# 17.继续从缓存区取
buf = fr.read(1024)
# 18.关闭文件
fr.close()
# 19.关闭连接
sock.close()
def upload_file(sock, data):
# 11.输出操作
print("上传")
# print(data)
# 12.获取文件名字
file_name = data[7:7 + int(data[2:7])].decode("utf-8")
# print(file_name)
# print("我是粘包", data)
# 13.获取粘包内容
file_last = data[7 + int(data[2:7]):]
# 14.打开文件
with open(file_name, "ab") as fw:
# 15.如果存在粘包,就把粘包也写进去
if file_last:
# 16.写入到文件
fw.write(file_last)
# 17.继续获取
raw_data = sock.recv(1024)
# 18.如果获取到消息
while raw_data:
# 19.写入到文件
fw.write(raw_data)
# 20.继续获取
raw_data = sock.recv(1024)
# 21.关闭文件
fw.close()
# 22.关闭连接
sock.close()
def main():
try:
# 1.创建对象
tcp_server = socket()
# 2.保证端口不被占用
tcp_server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
# 3.绑定端口
tcp_server.bind(("", 8988))
# 4.改主动为被动 注:只有在unix下生效
tcp_server.listen(5)
# 5.等待连接
while True:
# 6.解包
new_socket, client_info = tcp_server.accept()
# 7.接收消息
raw_data = new_socket.recv(1024)
# 8.判断客户有没有断开
if raw_data:
# 9.判断客户的命令
if raw_data[0:1] == b"L":
# 9.1查看文件列表
list_file(new_socket)
if raw_data[0:1] == b"D":
# 9.2下载
down_file(new_socket, raw_data)
if raw_data[0:1] == b"U":
# 9.3上传
upload_file(new_socket, raw_data)
else:
# 10.关闭
new_socket.close()
break
except:
new_socket.close()
if __name__ == '__main__':
main()