import selectors
import socket
import struct
import json
import os,sys
BASEDIR = os.path.dirname(__file__)
class Server:
def __init__(self):
self.dic = {}
self.sel = selectors.DefaultSelector()
self.makesock()
self.handle()
def makesock(self):
sock = socket.socket()
sock.bind(('127.0.0.1',8099))
sock.listen(5)
sock.setblocking(False)
self.sel.register(sock,selectors.EVENT_READ,self.accept)
def handle(self):
while True:
event = self.sel.select()
for key,mask in event:
func = key.data
func(key.fileobj,mask)
def accept(self,sock,mask):
conn,addr = sock.accept()
self.sel.register(conn,selectors.EVENT_READ,self.read)
self.dic[conn] = {}
def read(self,conn,mask):
if not self.dic[conn]:
try:
length = struct.unpack('i',conn.recv(4))[0]
cmd = json.loads(conn.recv(length).decode('utf8'))
except Exception as e:
print(e)
conn.close()
self.sel.unregister(conn)
return
if cmd['action'] == 'put':
conn.send(b'0')
f = open(os.path.basename(cmd['filename']),'wb')
if not cmd['filesize']:
f.close()
return
self.dic[conn] = cmd
self.dic[conn]['data_len'] = 0
self.dic[conn]['file'] = f
elif cmd['action'] == 'get':
path = os.path.join(BASEDIR,cmd['filename'])
if os.path.exists(path) and os.path.isfile(path):
filesize = os.path.getsize(path)
# print(filesize)
if filesize:
f = open(path,'rb')
self.dic[conn] = cmd
self.dic[conn]['file'] = f
conn.send(b'2')
conn.send(str(filesize).encode('utf8'))
else:
conn.send(b'1')
else:
conn.send(b'0')
else:
if hasattr(self,self.dic[conn]['action']):
func = getattr(self,self.dic[conn]['action'])
func(conn)
def get(self,conn):
data = self.dic[conn]['file'].read(1024)
if not data:
self.dic[conn]['file'].close()
self.dic[conn] = {}
return
status = conn.recv(1)
conn.send(data)
def put(self,conn):
if self.dic[conn]['data_len'] == self.dic[conn]['filesize']:
self.dic[conn]['file'].close()
self.dic[conn] = {}
return
data = conn.recv(1024)
self.dic[conn]['file'].write(data)
self.dic[conn]['data_len'] += len(data)
if __name__ == '__main__':
Server()
import socket
import struct
import json
import os,sys
class Client:
def __init__(self,ip_port):
self.ip_port = ip_port
self.makeconn()
self.handle()
def makeconn(self):
self.conn = socket.socket()
self.conn.connect(self.ip_port)
def handle(self):
while True:
cmd = input(">>>")
cmd = cmd.split()
if hasattr(self,cmd[0]):
func = getattr(self,cmd[0])
func(*cmd)
def jindu(self,size,filesize):
baifen_len = size / filesize
baifen = int(baifen_len * 100)
isok = 0
if baifen == 100:
r = '\r%s>%d%%\n' % ('=' * baifen, baifen,)
isok = 1
else:
r = "\r%s>%d%%"%('='*baifen,baifen,)
sys.stdout.write(r)
sys.stdout.flush
return isok
def get(self,*cmd):
data = {
"action" : "get",
"filename" : cmd[1]
}
data = json.dumps(data).encode('utf8')
length = struct.pack('i',len(data))
self.conn.send(length)
self.conn.send(data)
status = self.conn.recv(1).decode('utf-8')
if status == '0':
print("文件不存在")
return
f = open(os.path.basename(cmd[1]),'wb')
if status == '1':
f.close()
return
filesize = self.conn.recv(1024).decode('utf8')
filesize = int(filesize)
file_len = 0
while True:
self.conn.send(b'0')
file_data = self.conn.recv(1024)
file_len += len(file_data)
f.write(file_data)
if self.jindu(file_len,filesize):
f.close()
break
def put(self,*cmd):
data = {
"action": "put",
"filename": cmd[1],
}
if os.path.exists(cmd[1]) and os.path.isfile(cmd[1]):
filesize = os.path.getsize(cmd[1])
data['filesize'] = filesize
data = json.dumps(data).encode('utf8')
length = struct.pack('i', len(data))
self.conn.send(length)
self.conn.send(data)
status = self.conn.recv(1)
data_len = 0
with open(cmd[1],'rb') as f:
while True:
data = f.read(1024)
if not data: return
self.conn.send(data)
data_len += len(data)
if self.jindu(data_len, filesize):
break
else:
print("文件不存在")
return
if __name__ == '__main__':
c = Client(('127.0.0.1',8099))
c.handle()