python socket代码_python入门之socket代码练习

importsocketimportosimportjsonimporthashlib

user= "none" #当用户成功登录后,就会改变这个全局变量为当前用户名

classFtpClient(object):def __init__(self):

self.client=socket.socket()defconnection(self,ip,port):"""客户端去连接服务端

:param ip: 服务端IP地址

:param port: 服务端端口号"""self.client.connect((ip,port))deflogin(self):"""用户登录验证

:return:登录成功返回True,登录失败返回False"""m= hashlib.md5() #设定加密类型

username = input("[login]:").strip()

passw= input("[login]:").strip()

m.update(bytes(passw,encoding="utf-8")) #对密码进行加密

password = m.hexdigest() #返回十六进制的加密后的密码,加密时必须对bytes类型数据加密,使用bytes时必须指定encoding

user_dic ={"username":username,"password":password, #这里的密码已经是加密了的

"action":"login"}

user_dic_byte= str(json.dumps(user_dic)).encode() #将这个字典转化为bytes类型,传给服务端

self.client.send(user_dic_byte)

login_res_byte= self.client.recv(1024) #返回用户验证后的状态码(用户名或者密码对不对)

login_res =login_res_byte.decode()if login_res == "101": #用户名和密码正确

globaluser

user=usernameprint("Login successed")returnTrueelif login_res == "102": #用户存在,密码错误

print("password error")returnFalseelif login_res == "103": #用户不存在

print("user {} does not exist".format(username))returnFalsedefregist(self):"""用户注册"""m=hashlib.md5()

username= input("[regist]:").strip()

passw= input("[regist]:").strip()

m.update(bytes(passw,encoding="utf-8")) #加密时必须对bytes类型数据加密,使用bytes时必须指定encoding

password = m.hexdigest() #返回十六进制的加密后的密码

user_dic ={"username": username,"password": password, #这里的密码已经是加密了的

"action": "regist"}

user_dic_byte=str(json.dumps(user_dic)).encode()

self.client.send(user_dic_byte)

regist_res_byte= self.client.recv(1024)

regist_res=regist_res_byte.decode()if regist_res == "104": #用户注册成功

print("Regist successed")returnFalseelif regist_res == "105": #用户已经存在

print("user {} exist".format(username))returnFalsedefuserlogin(self):"""实现用户登录或注册的交互"""

whileTrue:

option= input("(L/l or G/g):").strip()if option.upper() == "L" andself.login():break

elif option.upper() == "G":

self.regist()else:continueself.interact()definteract(self):"""实行客户端与服务端的交互"""

whileTrue:

opt= input("[{}@ftpserver ~]#".format(user)).strip()if len(opt) == 0: continuecmd= opt.split()[0] #取出命令

if hasattr(self,cmd): #通过反射,执行相应的函数(一个命令对应一个函数,服务端也是如此)

func =getattr(self,cmd)

func(opt)else:

self.help()defhelp(self):"""命令使用帮助信息"""msg= """命令使用帮助:

ls 查看家目录下的文件目录

put file 上传文件

get file 下载文件

exit 退出当前用户"""

print(msg)defprogress(self,passed,all):"""进度条显示

:param passed: 已经进行过的长度

:param all: 进度条总长度"""s= passed * 100 //all

a= s * "#"b= (100 - s) * "-"

print('\r %d%% [%s%s]' % (s, a, b), end="") #光标回到行首,两个百分号表示输出一个百分号,end默认为\n,意为换行,改为空格就不换行

def put(self,*args):"""客户端上传文件"""cmd_list= args[0].split() #将命令和文件名分开

if len(cmd_list) > 1: #判断输入的命令是否正确,列表里命令加上文件名至少是两个元素

filename = cmd_list[1]if os.path.isfile(filename): #判断文件是否存在

filesize = os.stat(filename).st_size #获取文件的大小

file_dic ={"filename":filename,"filesize":filesize,"action":"put", #action是为了告诉服务端该执行什么操作

"fileuser":user #传这个值是因为要告诉服务端把文件放到哪个用户的家目录

}

self.client.send(json.dumps(file_dic).encode())

responce= self.client.recv(1024) #防止粘包,后续可用作验证返回

f = open(filename,"rb")

recvd_size=0for line inf:

recvd_size+=len(line)

self.progress(recvd_size,filesize)#进度条函数,传入已传文件大小和总文件大小

self.client.send(line)else:print("\nfile upload finish")

f.close()else:print("'" + filename + "': No such file")def get(self,*args):"""客户端下载文件"""cmd_list=args[0].split()if len(cmd_list) > 1:

filename= cmd_list[1]

file_dic={"filename":filename,"action":"get","fileuser": user

}

self.client.send(json.dumps(file_dic).encode())

file_size_byte= self.client.recv(1024) #传回的要么是文件大小,要么是状态码,下面就做判断

if file_size_byte.decode() != "404 none":

file_size=int(file_size_byte.decode())

self.client.send(b"100")

recvd_size=0ifos.path.isfile(filename):

f= open(filename + ".new","wb")else:

f= open(filename,"wb")while recvd_size < file_size: #判断已接收的文件大小和文件总大小

data = self.client.recv(1024)

f.write(data)

recvd_size+=len(data)

self.progress(recvd_size,file_size)#进度条

else:

f.close()print("\nfile has download")else:print("file no exist")def exit(self,*args):#退出当前用户

self.userlogin()def ls(self,*args):"""查看用户家目录下的所有文件"""ls_dic={"username":user,"action":"ls",

}

self.client.send(json.dumps(ls_dic).encode())

data= self.client.recv(1024)if data.decode() != "130 none": #要么返回列表,要么返回状态码

ls_list =json.loads(data.decode())for i inls_list:print(i)

ftp=FtpClient()

ftp.connection("localhost",9998)

ftp.userlogin()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值