socket 套接字总结
简单版
服务端
import socket import struct import json import os server_dir = r'E:\Moudule_1\socket练习\server\server_file' server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('127.1.1.1',8808)) server.listen(5) print('setting...') while True: conn, client_addr = server.accept() print(client_addr) while True: try: #1.接收命令 data = conn.recv(1024) print('客户端命令:',data) #2.接收报头长度 file_struct = conn.recv(4) file_len = struct.unpack('i',file_struct )[0] file_bytes = conn.recv(file_len) file_json = json.loads(file_bytes) file_name = file_json['filename'] total_size = file_json['filesize'] #将从客户端接收的文件数据写入 with open('%s/%s' %(server_dir,file_name), 'wb') as f: recv_size = 0 while recv_size < total_size: line = conn.recv(1024) f.write(line) recv_size += len(line) print('总大小:%s 已下载大小:%s' % (total_size, recv_size)) except: exit() conn.close() server.close()
客户端
import socket import struct import json import os client_dir = r'E:\Moudule_1\socket练习\client\download' client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(('127.1.1.1',8808)) while True: #1.发送命令 inp = input('>>:') if not inp:continue client.send(inp.encode('utf-8')) #将文件的以读的方式打开,将数据发送给server #1.固定报头长度 filename = inp.split()[1] filesize = os.path.getsize(os.path.join(client_dir, filename)) file_data = { 'filename' : filename, 'filesize' : filesize } file_json = json.dumps(file_data) file_bytes = file_json.encode('utf-8') file_struct = struct.pack('i', len(file_bytes)) #2.发送报头长度 client.send(file_struct) #3.发送报头 client.send(file_bytes) #4.向server发送真实的数据 with open('%s/%s' %(client_dir, filename), 'rb') as f: for line in f: client.send(line) client.close()
优化版
服务端
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # Author:Mr.yang import socket import struct import json import os server_dir = r'E:\Moudule_1\socket练习\优化版\server\server_file' server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('127.1.1.1', 8808)) server.listen(5) def put(conn): # 2.接收报头长度 file_struct = conn.recv(4) file_len = struct.unpack('i', file_struct)[0] file_bytes = conn.recv(file_len) file_json = json.loads(file_bytes) file_name = file_json['filename'] total_size = file_json['filesize'] # 将从客户端接收的文件数据写入 with open('%s/%s' % (server_dir, file_name), 'wb') as f: recv_size = 0 while recv_size < total_size: line = conn.recv(1024) f.write(line) recv_size += len(line) result = '总大小:%s 已上传大小:%s' % (total_size, recv_size) conn.send(result.encode('utf-8')) def get(conn,data): # 将文件的以读的方式打开,将数据发送给client # 1.固定报头长度 filename = data.split()[1] filesize = os.path.getsize(os.path.join(server_dir, filename)) file_data = { 'filename': filename, 'filesize': filesize } file_json = json.dumps(file_data) file_bytes = file_json.encode('utf-8') file_struct = struct.pack('i', len(file_bytes)) # 2.发送报头长度 conn.send(file_struct) # 3.发送报头 conn.send(file_bytes) # 4.向client发送真实的数据 with open('%s/%s' % (server_dir, filename), 'rb') as f: for line in f: conn.send(line) def run(): print('setting...') while True: conn, client_addr = server.accept() print(client_addr) while True: try: #1.接收命令 data = conn.recv(1024).decode('utf-8') print('客户端命令:',data) cmd =data.split()[0] if cmd == 'put': put(conn) elif cmd == 'get': get(conn,data) except: exit() conn.close() server.close() if __name__ == '__main__': run()
客户端
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # Author:Mr.yang import socket import struct import json import os upload_dir = r'E:\Moudule_1\socket练习\优化版\client\upload' download_dir = r'E:\Moudule_1\socket练习\优化版\client\download' client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(('127.1.1.1', 8808)) def put(inp): # 将文件的以读的方式打开,将数据发送给server # 1.固定报头长度 filename = inp.split()[1] filesize = os.path.getsize(os.path.join(upload_dir, filename)) file_data = { 'filename': filename, 'filesize': filesize } file_json = json.dumps(file_data) file_bytes = file_json.encode('utf-8') file_struct = struct.pack('i', len(file_bytes)) # 2.发送报头长度 client.send(file_struct) # 3.发送报头 client.send(file_bytes) # 4.向server发送真实的数据 with open('%s/%s' % (upload_dir, filename), 'rb') as f: for line in f: client.send(line) result = client.recv(1024) print(result.decode('utf-8')) def get(): file_struct = client.recv(4) file_len = struct.unpack('i', file_struct)[0] file_bytes = client.recv(file_len) file_json = json.loads(file_bytes) file_name = file_json['filename'] total_size = file_json['filesize'] # 将从server接收的文件数据写入 with open('%s/%s' % (download_dir, file_name), 'wb') as f: recv_size = 0 while recv_size < total_size: line = client.recv(1024) f.write(line) recv_size += len(line) print('总大小:%s 已上传大小:%s' % (total_size, recv_size)) def run(): while True: #1.发送命令 inp = input('>>:') if not inp:continue cmd = inp.split()[0] client.send(inp.encode('utf-8')) if cmd == 'put': put(inp) if cmd == 'get': get() client.close() if __name__ == '__main__': run()
面向对象版
服务端
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # Author:Mr.yang import socket import struct import json import os class MYTCPServer: address_family = socket.AF_INET # 地址家族 socket_type = socket.SOCK_STREAM # 基于TCP协议的流水型 server_dir = r'E:\Moudule_1\socket练习\优化版\server\server_file' allow_reuse_address = False # 是否重复使用IP地址 max_packet_size = 8192 # 最大的数据包大小 request_queue_size = 5 # 允许链接的大小 def __init__(self,server_address, bind_and_activate=True): 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): 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): self.socket.listen(self.request_queue_size) # 设置最大接听数 def server_close(self): self.socket.close() #关闭 def get_request(self): return self.socket.accept() # 建立链接 def run(self,): print('setting...') while True: self.conn, client_addr = self.get_request() print(client_addr) while True: try: #1.接收命令 data = self.conn.recv(1024).decode('utf-8') print('客户端命令:',data) cmd =data.split()[0] if hasattr(self,cmd): func = getattr(self,cmd) func(data) except: exit() def put(self,data): # 2.接收报头长度 file_result = self.conn.recv(self.max_packet_size).decode('utf-8') if file_result == '0': file_struct = self.conn.recv(4) file_len = struct.unpack('i', file_struct)[0] file_bytes = self.conn.recv(file_len) file_json = json.loads(file_bytes) file_name = file_json['filename'] total_size = file_json['filesize'] # 将从客户端接收的文件数据写入 with open('%s/%s' % (self.server_dir, file_name), 'wb') as f: recv_size = 0 while recv_size < total_size: line = self.conn.recv(1024) f.write(line) recv_size += len(line) result = '总大小:%s 已上传大小:%s' % (total_size, recv_size) self.conn.send(result.encode('utf-8')) else: print('文件不存在') def get(self,data): # 将文件的以读的方式打开,将数据发送给client # 1.固定报头长度 filename = data.split()[1] filepath = os.path.join(self.server_dir, filename) if os.path.exists(filepath): self.conn.send('0'.encode('utf-8')) filesize = os.path.getsize(filepath) file_data = { 'filename': filename, 'filesize': filesize } file_json = json.dumps(file_data) file_bytes = file_json.encode('utf-8') file_struct = struct.pack('i', len(file_bytes)) # 2.发送报头长度 self.conn.send(file_struct) # 3.发送报头 self.conn.send(file_bytes) # 4.向client发送真实的数据 with open('%s/%s' % (self.server_dir, filename), 'rb') as f: for line in f: self.conn.send(line) else: self.conn.send('1'.encode('utf-8')) print('文件不存在') obj = MYTCPServer(('127.1.1.1', 8808)) obj.run()
客户端
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # Author:Mr.yang import socket import struct import json import os class MYTCPClient: address_family = socket.AF_INET # 地址家族 socket_type = socket.SOCK_STREAM # 基于TCP协议的流水型 allow_reuse_address = False # 是否重复使用IP地址 max_packet_size = 8192 # 最大的数据包大小 request_queue_size = 5 # 允许链接的大小 upload_dir = r'E:\Moudule_1\socket练习\优化版\client\upload' download_dir = r'E:\Moudule_1\socket练习\优化版\client\download' def __init__(self,sever_address, connect=True): self.server_address = sever_address self.socket = socket.socket(self.address_family, self.socket_type) if connect: try: self.client_connect() except: self.client_close raise def client_connect(self): self.socket.connect(self.server_address) # 创建双线管道链接 def client_close(self): self.socket.close() def put(self,inp): # 将文件的以读的方式打开,将数据发送给server # 1.固定报头长度 filename = inp.split()[1] filepath = os.path.join(self.upload_dir, filename) if os.path.exists(filepath): # 判断文件是否存在 self.socket.send('0'.encode('utf-8')) filesize = os.path.getsize(filepath) file_data = { 'filename': filename, 'filesize': filesize } file_json = json.dumps(file_data) file_bytes = file_json.encode('utf-8') file_struct = struct.pack('i', len(file_bytes)) # 2.发送报头长度 self.socket.send(file_struct) # 3.发送报头 self.socket.send(file_bytes) # 4.向server发送真实的数据 with open('%s/%s' % (self.upload_dir, filename), 'rb') as f: for line in f: self.socket.send(line) result = self.socket.recv(1024) print(result.decode('utf-8')) else: self.socket.send('1'.encode('utf-8')) print('文件不存在') def get(self,inp): file_result = self.socket.recv(self.max_packet_size).decode('utf-8') if file_result == '0': file_struct = self.socket.recv(4) file_len = struct.unpack('i', file_struct)[0] file_bytes = self.socket.recv(file_len) file_json = json.loads(file_bytes) file_name = file_json['filename'] total_size = file_json['filesize'] # 将从server接收的文件数据写入 with open('%s/%s' % (self.download_dir, file_name), 'wb') as f: recv_size = 0 while recv_size < total_size: line = self.socket.recv(1024) f.write(line) recv_size += len(line) print('总大小:%s 已上传大小:%s' % (total_size, recv_size)) else: print('文件不存在') def run(self): while True: #1.发送命令 inp = input('>>:') if not inp:continue cmd = inp.split()[0] self.socket.send(inp.encode('utf-8')) if hasattr(self, cmd): func = getattr(self, cmd) func(inp) obj = MYTCPClient(('127.1.1.1', 8808)) obj.run()