项目: 基于Python socket模块实现的简单 ftp 项目:
需要 自己创建一个 info 文件 用来存储用户信息
服务器:
import socket
import pickle
import struct
import os
import time ''.startswith('vip') class Mysocket(socket.socket):
"""此类 重写socket类的reve和send方法, 表示如果发送的是字符串 直接调用这两个方法即可""" def __init__(self, encoding='utf-8'):
self.encoding = encoding
super().__init__() def my_reve(self, num):
msg = self.recv(num).decode(self.encoding)
return msg def my_send(self, msg): return self.send(msg.encode(self.encoding)) class ServerFTP(socket.socket):
def __init__(self):
self.flag = True
self.path_dir = None
self.vip = ''
super().__init__() def up_vip(self,dict_client, login_dict_2):
try:
if not ('vip' in self.path_dir):
print(dict_client['username'])
old_name = dict_client['username']
self.vip = 'vip'
print(7758521)
self.new_name = self.vip + dict_client['username']
os.rename(old_name,self.new_name)
login_dict_2['vip_ret'] = '升级成功'
except Exception:login_dict_2['vip_ret'] ='您已经是vip了,扩容失败' def upload(self, path_dir, dict_client_2, login_dict_2,dict_client):
file_name = dict_client_2['file_name']
file_size = dict_client_2['file_size']
now_dir_name = os.path.join(path_dir, file_name)
with open(now_dir_name, 'wb') as f:
while file_size>0:
content = self.conn.recv(1024)
f.write(content)
file_size -= len(content)
login_dict_2['listdir'] = os.listdir(path_dir)
print(1) def download(self, path_dir, dict_client_2, login_dict_2):
file_path = os.path.join(path_dir, dict_client_2['file_name'])
dict_client_2['file_size'] = os.path.getsize(file_path)
file_size = dict_client_2['file_size']
self.conn.send(struct.pack('i', file_size))
with open(file_path, 'rb') as f:
while file_size:
if file_size<1024:content = f.read(file_size)
else:content = f.read(1024)
self.conn.send(content)
file_size -= len(content)
login_dict_2['listdir'] = os.listdir(path_dir) def login(self, dict_client):
login_dict = {}
with open('../db/info', encoding='utf-8') as f:
for line in f:
if dict_client['username'] + '\t' + dict_client['password'] == line.strip():
login_dict['opt'] = '登录成功'
try:
name = 'vip'+dict_client['username']
self.path_dir = os.path.join(os.path.dirname(__file__), name)
login_dict['listdir'] = os.listdir(self.path_dir)
except Exception:
self.path_dir = os.path.join(os.path.dirname(__file__), dict_client['username'])
login_dict['listdir'] = os.listdir(self.path_dir)
try:
login_dict['容量'] = '%s/%s (单位:字节)' % (
os.path.getsize(os.path.dirname(__file__) + '/vip' +dict_client['username']), 1024 * 10000)
except Exception:
login_dict['容量'] = '%s/%s (单位:字节)' % (
os.path.getsize(os.path.dirname(__file__) + '/' + dict_client['username']), 1024 * 100)
self.conn.send(struct.pack('i', len(pickle.dumps(login_dict))) + pickle.dumps(login_dict))
while self.flag:
self.main_2(dict_client) return
login_dict['opt'] = '登录失败'
self.conn.send(struct.pack('i', len(pickle.dumps(login_dict))) + pickle.dumps(login_dict))
return def register(self, dict_client):
register_dict = {}
with open('../db/info', 'r+', encoding='utf-8') as f:
for line in f:
if dict_client['username'] == line.strip().split('\t')[0]:
register_dict['opt'] = '用户名已存在'
self.conn.send(struct.pack('i', len(pickle.dumps(register_dict))) + pickle.dumps(register_dict))
return
register_dict['opt'] = '注册成功'
f.seek(0, 2)
f.write(dict_client['username'] + '\t' + dict_client['password'] + '\n')
os.mkdir(dict_client['username'])
path_user = os.path.join(os.path.dirname(__file__), dict_client['username'])
for i in range(3):
os.mkdir(os.path.join(path_user, str(i)))
self.conn.send(struct.pack('i', len(pickle.dumps(register_dict))) + pickle.dumps(register_dict))
time.sleep(5)
return def main_2(self, dict_client):
login_dict_2 = {}
dict_client_2 = pickle.loads(self.conn.recv(struct.unpack('i', self.conn.recv(4))[0])) # reve_2 接受 选择和文件内容
if dict_client_2['opt'] == '':
self.path_dir = os.path.join(os.path.dirname(self.path_dir),self.vip+os.path.basename(self.path_dir))
self.path_dir = os.path.join(self.path_dir, dict_client_2['filename'])
login_dict_2['listdir'] = os.listdir(self.path_dir)
print('进入下一层了')
elif dict_client_2['opt'] == '':
print('想访问上一层了')
print(self.path_dir)
self.path_dir_2 = os.path.dirname(self.path_dir)
print(self.path_dir_2)
if self.path_dir_2 == os.path.dirname(__file__):
login_dict_2['listdir'] = '已经到底了 没有内容了哦'
else:
self.path_dir = self.path_dir_2
login_dict_2['listdir'] = os.listdir(self.path_dir)
elif dict_client_2['opt'] == '':
print('想传东西了')
self.upload(self.path_dir, dict_client_2, login_dict_2, dict_client)
print('传完了')
elif dict_client_2['opt'] == '':
self.download(self.path_dir, dict_client_2, login_dict_2)
elif dict_client_2['opt'] == '':
self.up_vip(dict_client,login_dict_2)
elif dict_client_2['opt'] == '':
self.flag = False
return
self.conn.send(struct.pack('i', len(pickle.dumps(login_dict_2))) + pickle.dumps(login_dict_2)) def main(self, conn):
while 1:
head_client = conn.recv(4)
try:
dict_client = pickle.loads(conn.recv(struct.unpack('i', head_client)[0]))
print('来看看他发的啥哈哈哈')
if dict_client['opt'] == '':
self.login(dict_client)
elif dict_client['opt'] == '':
self.register(dict_client)
except struct.error:
return def __call__(self, *args, **kwargs):
sk = socket.socket()
sk.bind(('192.168.19.15', 8888))
sk.listen()
while 1:
self.conn, addr = sk.accept()
print('连上了')
self.main(self.conn)
self.conn.close() if __name__ == '__main__':
ftp_s = ServerFTP()
ftp_s()
客户端:
import socket
import hashlib
import pickle
import struct
import os class Mysocket(socket.socket):
"""此类 重写socket类的reve和send方法, 表示如果发送的是字符串 直接调用这两个方法即可""" def __init__(self, encoding='utf-8'):
self.encoding = encoding
super().__init__() def my_reve(self, num):
msg = self.recv(num).decode(self.encoding)
return msg def my_send(self, msg): return self.send(msg.encode(self.encoding)) def upload(login_dict):
file_dir = input('>>>请输入文件名:').strip()
file_name = os.path.basename(file_dir)
login_dict['file_name'] = file_name
file_size = os.path.getsize(file_dir)
login_dict['file_size'] = file_size
sk.send(struct.pack('i', len(pickle.dumps(login_dict))) + pickle.dumps(login_dict)) # send_2 : 发送选择 或者 选择和文件
with open(file_dir, 'rb') as f:
while file_size:
content = f.read(1024)
sk.send(content)
file_size -= len(content) def download(login_dict):
file_name = input('>>>下载文件的名字:').strip()
down_path = input('>>>本地下载文件路径:').strip()
login_dict['file_name'] = file_name
sk.send(struct.pack('i', len(pickle.dumps(login_dict))) + pickle.dumps(login_dict))
down_file_size = struct.unpack('i', sk.recv(4))[0]
with open(down_path, 'wb') as f:
while down_file_size:
if down_file_size < 1024:
content = sk.recv(down_file_size)
else:content = sk.recv(1024)
f.write(content)
down_file_size -= len(content) def up_vip(usn): pass def login(dict_server, usn):
login_dict = {}
print(dict_server['listdir'])
while 1:
print('1, 进入下级文件目录\n'
'2, 返回上层目录\n'
'3, 在该目录上传文件\n'
'4, 下载该目录下的某个文件\n'
'5, 升级为VIP\n'
'6, 退出程序')
opt = input('>>>请选择功能:').strip()
login_dict['opt'] = opt
if opt == '':
login_dict['filename'] = input('>>>文件名')
sk.send(
struct.pack('i', len(pickle.dumps(login_dict))) + pickle.dumps(login_dict)) # send_2 : 发送选择 或者 选择和文件 elif opt == '':
upload(login_dict)
print('上传成功')
elif opt == '':
download(login_dict)
print('下载成功')
elif opt == '': # 升级VIP还待补充.
print('将扩大100倍的容量')
up_vip(usn)
sk.send(
struct.pack('i', len(pickle.dumps(login_dict))) + pickle.dumps(login_dict)) # send_2 : 发送选择 或者 选择和文件 if opt == '':
global flag
flag = False
return
dict_server_2 = pickle.loads(sk.recv(struct.unpack('i', sk.recv(4))[0]))
try:
print(dict_server_2['listdir'])
except KeyError:
print(dict_server_2['vip_ret']) def main():
while flag:
print('1, 登录\n2, 注册')
opt = input('>>>选择功能:').strip()
if opt != '' and opt != '':
print('输入错误,程序结束')
return
dic['opt'] = opt
usn = input('>>>Username:').strip()
dic['username'] = usn
pwd = input('>>>Password:').strip()
md5_obj = hashlib.md5(usn.encode('utf-8'))
md5_obj.update(pwd.encode('utf-8'))
pwd = md5_obj.hexdigest()
dic['password'] = pwd
dic_pic = pickle.dumps(dic)
head = struct.pack('i', len(dic_pic))
sk.send(head + dic_pic) # send 1: 把登录/注册 + 用户名 + 密码发送给服务器
head_server = sk.recv(4)
dict_server = pickle.loads(sk.recv(struct.unpack('i', head_server)[0]))
print(dict_server['opt'])
if dict_server['opt'] == '登录成功':
print(dict_server['容量'])
login(dict_server, usn) if __name__ == '__main__':
flag = True
dic = {'opt': '请求的功能', } sk = Mysocket()
sk.connect_ex(('192.168.19.15', 8888)) main() sk.close()
项目: 基于Python socket模块实现的简单 ftp 项目:的更多相关文章
- python——socket模块与列表映射
从socket模块学习中的一段奇怪代码说起 前言:在学习python标准库中的Socket模块中,发现了一段奇怪的代码. import socket def get_constants(prefix) ...
- 一小时学会用Python Socket 开发可并发的FTP服务器!!
socket是什么 什么是socket所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络发出请求 ...
- 用python socket模块实现简单的文件下载
server端: # ftp server端 import socket, os, time server = socket.socket() server.bind(("localhost ...
- python - socket模块1
1.使用生活中的接打电话,解释socket通信流程 2.根据上图,写出socket通信的伪代码 2.1.server端伪代码 #买手机 #买手机卡 #开机 #等待电话 #收消息 #发消息 #挂电 ...
- Selenium网页自动登录项目(基于Python从0到1)
Selenium是一个自动化测试工具,利用它我们可以驱动浏览器执行特定的动作,如点击.下拉等操作. 本文讲述的是通过自动化的方式登陆某一网站,其中包含Selenium+python自动化项目环境如何部 ...
- python socket 常见方法及 简单服务/客户端
socket 常见方法: 补充说明:what is file descriptor? 文件描述符是什么? 参考(http://stackoverflow.com/questions/8191905/w ...
- python socket编程实现的简单tcp迭代server
与c/c++ socket编程对照见http://blog.csdn.net/aspnet_lyc/article/details/38946915 server: import socket POR ...
- python --- socket模块详解
socket常用功能函数: socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None) ...
- Python socket套接字简单例子
随机推荐
- hdu 2647 Reward(拓扑排序+优先队列)
Problem Description Dandelion's uncle is a boss of a factory. As the spring festival is coming , he ...
- Python的matplotlib库画图不能显示中文问题解决
有两种解决办法: 一种是在代码里设置为能显示中文的字体,如微软雅黑(msyh.ttf)和黑体(simsun.ttc) 如下在要画图的代码前添加: import matplotlib.pyplot as ...
- S-Nim POJ - 2960 Nim + SG函数
Code: #include<cstdio> #include<algorithm> #include<string> #include<cstring> ...
- C#中Dictionary排序方式
转载自:https://www.cnblogs.com/5696-an/p/5625142.html 自定义类: https://files.cnblogs.com/files/xunhanliu/d ...
- [译] 我最终是怎么玩转了 Vue 的作用域插槽
原文链接:https://juejin.im/post/5c8856e6e51d456b30397f31#comment 原文地址:How I finally got my head around S ...
- 洛谷1005 【NOIP2007】矩阵取数游戏
问题描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. ...
- 紫书 例题 10-21 UVa 11971(连续概率)
感觉这道题的转换真的是神来之笔 把木条转换成圆,只是切得次数变多一次 然后只要有一根木条长度为直径就租不成 其他点的概率为1/2^k 当前这个点的有k+1种可能 所以答案为1 - (k+1)/2^k ...
- Java排序算法(二):简单选择排序
[基本思想] 在要排序的一组数中.选出最小的一个数与第一个位置的数交换:然后在剩下的数中再找出最小的与第二个位置的数交换,如此循环至倒数第二个数和最后一个数比較为止. 算法关键:找到最小的那个数.并用 ...
- java 自己定义异常,记录日志简单说明!留着以后真接复制
log4j 相关配制说明:http://blog.csdn.net/liangrui1988/article/details/17435139 自己定义异常 package org.rui.Excep ...
- POJ 3070 Fibonacci 矩阵高速求法
就是Fibonacci的矩阵算法.只是添加一点就是由于数字非常大,所以须要取10000模,计算矩阵的时候取模就能够了. 本题数据不强,只是数值本来就限制整数,故此能够0ms秒了. 以下程序十分清晰了, ...