简易版服务器server
import socket,struct,json sk = socket.socket() buffer = 1024 #每次接收数据的大小 sk.bind(('127.0.0.1',8090)) sk.listen() conn,addr = sk.accept() #接收 head_len = conn.recv(4) head_len = struct.unpack('i',head_len)[0] #解包 json_head = conn.recv(head_len).decode('utf-8') #反序列化 head = json.loads(json_head) filesize = head['filesize'] with open(head['filename'],'wb') as f: while filesize: if filesize >= buffer: #>=是因为如果刚好等于的情况出现也是可以的。 content = conn.recv(buffer) f.write(content) filesize -= buffer else: content = conn.recv(buffer) f.write(content) break conn.close() sk.close()
简易版客户端client
1 import os,json,socket,struct 2 sk = socket.socket() 3 sk.connect(('127.0.0.1',8090)) 4 buffer = 1024 #读取文件的时候,每次读取的大小 5 head = { 6 'filepath':r'D:打包程序', #需要下载的文件路径,也就是文件所在的文件夹 7 'filename':'xxx.mp4', #改成上面filepath下的一个文件 8 'filesize':None, 9 } 10 11 file_path = os.path.join(head['filepath'],head['filename']) 12 filesize = os.path.getsize(file_path) 13 head['filesize'] = filesize 14 # json_head = json.dumps(head,ensure_ascii=False) #字典转换成字符串 15 json_head = json.dumps(head) #字典转换成字符串 16 bytes_head = json_head.encode('utf-8') #字符串转换成bytes类型 17 print(json_head) 18 print(bytes_head) 19 20 #计算head的长度,因为接收端先接收我们自己定制的报头,对吧 21 head_len = len(bytes_head) #报头长度 22 pack_len = struct.pack('i',head_len) 23 print(head_len) 24 print(pack_len) 25 sk.send(pack_len) #先发送报头长度 26 sk.send(bytes_head) #再发送bytes类型的报头 27 28 #即便是视频文件,也是可以按行来读取的,也可以readline,也可以for循环,但是读取出来的数据大小就不固定了,影响效率,有可能读的比较小,也可能很大,像视频文件一般都是一行的二进制字节流。 29 #所有我们可以用read,设定一个一次读取内容的大小,一边读一边发,一边收一边写 30 with open(file_path,'rb') as f: 31 while filesize: 32 if filesize >= buffer: #>=是因为如果刚好等于的情况出现也是可以的。 33 content = f.read(buffer) #每次读取出来的内容 34 sk.send(content) 35 filesize -= buffer #每次减去读取的大小 36 else: #那么说明剩余的不够一次读取的大小了,那么只要把剩下的读取出来发送过去就行了 37 content = f.read(filesize) 38 sk.send(content) 39 break 40 41 sk.close()
实现的功能是客户端拟定一个文件传输路径然后再传送到服务器上面,相当于保存在网络云盘里面,如果是下载功能及相反,显示服务器里面自己拥有的文件夹,然后客户端进行接收,属于下载功能.
升级版服务器server
import socket import struct import json import subprocess import os class MYTCPServer: address_family = socket.AF_INET socket_type = socket.SOCK_STREAM allow_reuse_address = False max_packet_size = 8192 coding='utf-8' request_queue_size = 5 server_dir='file_upload' def __init__(self, server_address, bind_and_activate=True): """Constructor. May be extended, do not override.""" self.server_address=server_address self.socket = socket.socket(self.address_family, self.socket_type) if bind_and_activate: try: self.server_bind() self.server_activate() except: self.server_close() raise def server_bind(self): """Called by constructor to bind the socket. """ if self.allow_reuse_address: self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.socket.bind(self.server_address) self.server_address = self.socket.getsockname() def server_activate(self): """Called by constructor to activate the server. """ self.socket.listen(self.request_queue_size) def server_close(self): """Called to clean-up the server. """ self.socket.close() def get_request(self): """Get the request and client address from the socket. """ return self.socket.accept() def close_request(self, request): """Called to clean up an individual request.""" request.close() def run(self): while True: self.conn,self.client_addr=self.get_request() print('from client ',self.client_addr) while True: try: head_struct = self.conn.recv(4) if not head_struct:break head_len = struct.unpack('i', head_struct)[0] head_json = self.conn.recv(head_len).decode(self.coding) head_dic = json.loads(head_json) print(head_dic) #head_dic={'cmd':'put','filename':'a.txt','filesize':123123} cmd=head_dic['cmd'] if hasattr(self,cmd): func=getattr(self,cmd) func(head_dic) except Exception: break def put(self,args): file_path=os.path.normpath(os.path.join( self.server_dir, args['filename'] )) filesize=args['filesize'] recv_size=0 print('----->',file_path) with open(file_path,'wb') as f: while recv_size < filesize: recv_data=self.conn.recv(self.max_packet_size) f.write(recv_data) recv_size+=len(recv_data) print('recvsize:%s filesize:%s' %(recv_size,filesize)) tcpserver1=MYTCPServer(('127.0.0.1',8080)) tcpserver1.run()
升级版客户端client
1 import socket 2 import struct 3 import json 4 import os 5 6 7 class MYTCPClient: 8 address_family = socket.AF_INET 9 10 socket_type = socket.SOCK_STREAM 11 12 allow_reuse_address = False 13 14 max_packet_size = 8192 15 16 coding='utf-8' 17 18 request_queue_size = 5 19 20 def __init__(self, server_address, connect=True): 21 self.server_address=server_address 22 self.socket = socket.socket(self.address_family, 23 self.socket_type) 24 if connect: 25 try: 26 self.client_connect() 27 except: 28 self.client_close() 29 raise 30 31 def client_connect(self): 32 self.socket.connect(self.server_address) 33 34 def client_close(self): 35 self.socket.close() 36 37 def run(self): 38 while True: 39 inp=input(">>: ").strip() 40 if not inp:continue 41 l=inp.split() 42 cmd=l[0] 43 if hasattr(self,cmd): 44 func=getattr(self,cmd) 45 func(l) 46 47 48 def put(self,args): 49 cmd=args[0] 50 filename=args[1] 51 if not os.path.isfile(filename): 52 print('file:%s is not exists' %filename) 53 return 54 else: 55 filesize=os.path.getsize(filename) 56 57 head_dic={'cmd':cmd,'filename':os.path.basename(filename),'filesize':filesize} 58 print(head_dic) 59 head_json=json.dumps(head_dic) 60 head_json_bytes=bytes(head_json,encoding=self.coding) 61 62 head_struct=struct.pack('i',len(head_json_bytes)) 63 self.socket.send(head_struct) 64 self.socket.send(head_json_bytes) 65 send_size=0 66 with open(filename,'rb') as f: 67 for line in f: 68 self.socket.send(line) 69 send_size+=len(line) 70 print(send_size) 71 else: 72 print('upload successful') 73 74 75 76 client=MYTCPClient(('127.0.0.1',8080)) 77 78 client.run()