python学习笔记——捌 ScoketServer

服务端:

import socketserver
import json,os
import hashlib
class MyTCPHandler(socketserver.BaseRequestHandler):



def put(self,*args):
server_md5=hashlib.md5()
'''接收客户端文件'''
cmd_dic = args[0]
filename = cmd_dic["filename"]
filesize = cmd_dic["size"]
if os.path.isfile(filename):
f = open(filename + ".new","wb")
else:
f = open(filename , "wb")

self.request.send(b"200 ok")
received_size = 0
while received_size < filesize:
data = self.request.recv(1024)
server_md5.update(data)
f.write(data)
received_size += len(data)

else:
print("file [%s] has uploaded..." % filename)

self.request.send(server_md5.hexdigest().encode())

def get(self,*args):
md5_server=hashlib.md5()
#接收客户端的信息
cmd_dic=args[0]
#得到文件名称
filename=cmd_dic["filename"]
#判断是不是个文件
if os.path.isfile(filename):
#得到文件大小
file_size=os.stat(filename).st_size
#j将文件大小发送给客户端
self.request.send(str(file_size).encode())
#对应客户端的胡写,防止粘包
self.request.recv(1024)
#开始发送文件了
f=open(filename,"rb")
for line in f :
self.request.send(line)
md5_server.update(line)
#将MD5后的值 发送给客户端
print(md5_server.hexdigest())
self.request.send((md5_server.hexdigest()).encode())
else:
print("服务端没有此文件")


def handle(self):

while True:
try:
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
cmd_dic = json.loads(self.data.decode())
action = cmd_dic["action"]
if hasattr(self,action):
func = getattr(self,action)
func(cmd_dic)

except ConnectionResetError as e:
print("err",e)
break


if __name__ == "__main__":
HOST, PORT = "localhost", 9997
# Create the server, binding to localhost on port 9999
server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
server.serve_forever()



客户端
_author__ = "Alex Li"
import socket
import json
import os
import hashlib
#用于打印进度条
import sys,time


# client.connect(('192.168.16.200',9999))



class FtpClient(object):
def __init__(self):
self.client = socket.socket()

def help(self):
msg = '''
ls
pwd
cd ../..
get filename
put filename
'''
print(msg)

def connect(self, ip, port):
self.client.connect((ip, port))
#利用反射,通过输入的字符串 来调用不同的方法
def interactive(self):
md5_client=hashlib.md5()
# self.authenticate()

#执行操作的代码
while True:
cmd = input(">>").strip()
if len(cmd) == 0: continue
cmd_str = cmd.split()[0]
if hasattr(self, "cmd_%s" % cmd_str):
func = getattr(self, "cmd_%s" % cmd_str)
func(cmd)
else:
self.help()


def cmd_put(self, *args):
cmd_split = args[0].split()
if len(cmd_split) > 1:
filename = cmd_split[1]
if os.path.isfile(filename):
filesize = os.stat(filename).st_size
msg_dic = {
"action": "put",
"filename": filename,
"size": filesize,
"overridden": True
}
self.client.send(json.dumps(msg_dic).encode("utf-8"))
print("send", json.dumps(msg_dic).encode("utf-8"))
# 防止粘包,等服务器确认
server_response = self.client.recv(1024)
f = open(filename, "rb")
#用于MD5校验
client_md5=hashlib.md5()
#用于计算发送了多少数据
clien_size=0
b=0
for line in f:
self.client.send(line)
client_md5.update(line)
clien_size +=len(line)

# 计算接收的数据 占 总文件的百分比
a = int(clien_size / filesize * 100)
if b != a and a % 2 == 0:
# print("%d" % a + "%")
sys.stdout.write("#")
sys.stdout.flush()
else:
pass
b = a
else:
print("100%")
f.close()
#客户端发送数据的md5值
client_md5=client_md5.hexdigest()

else:
print(filename, "is not exist")

server_ma5=self.client.recv(1024)
server_ma5=server_ma5.decode()
#判断 两边的md5值是否是一致的
if server_ma5==client_md5:
print("文件成功上传至服务器")
else:
print("上传出错")



def cmd_get(self, *args):
# 用md5对比文件是否一致
md5_clent = hashlib.md5()
'''此方法用于下载操作'''
# 把输入的命令 按空格分隔 切分成列表
cmd_split = args[0].split()
# 如果命令的长度大于0
if len(cmd_split) > 1:
# 得到文件名
filename = cmd_split[1]
# 服务端那边解析的是一个字典,所以我也写个字典

msg_dic = {
"action": "get",
"filename": filename
}
print(msg_dic)
# 将动作和文件名发给服务端
self.client.send(json.dumps(msg_dic).encode("utf-8"))
print("发送完毕")

# 获得服务端文件的大小
size = self.client.recv(1024).decode()
print(type(size))
print(size)
server_size = int(size)
print("获得服务器文件的大小是%s" % server_size)
# 胡写一个,防止粘包
self.client.send(b"jiehsou wenjian")
# 准备接受 服务端发来的数据
# 已经获取文件的大小
clien_size = 0
if os.path.isfile(filename):
f = open(filename + "new", "wb")
else:
f = open(filename, "wb")
#防止重复出现相同的百分比 而设置的变量
b=0
while clien_size < server_size:
if server_size - clien_size > 1024:
data_size = 1024
else:
data_size = server_size - clien_size

data=self.client.recv(data_size)
md5_clent.update(data)
f.write(data)
#计算接收过来的数据长度
clien_size += len(data)

#计算接收的数据 占 总文件的百分比
a=int(clien_size/server_size*100)
if b!=a and a%2==0:
# print("%d" % a + "%")
sys.stdout.write("#")
sys.stdout.flush()
else:
pass
b=a


# 接收server过来的md5值
server_md51 = self.client.recv(1024)
server_md52 = server_md51.decode()
clien_md5= md5_clent.hexdigest()
# print("md5_server1--%s" % server_md51)
# print("md5_server2--%s" % server_md52)
#
# print("md5_client--%s" % clien_md5)
# print(server_md51==clien_md5)
# print(server_md52==clien_md5)
if server_md52==clien_md5 :
print("100%")
else:
print("文件可能被篡改,请重新下载")


ftp = FtpClient()
ftp.connect("localhost", 9997)
ftp.interactive()



原文地址:https://www.cnblogs.com/HL-blog/p/7593350.html