socket 文件传输
函数版
服务端
import socket import struct import json import os def get(conn, cmd): file_name = cmd[1] file_size = os.path.getsize('%s/%s' % (service_path, file_name)) header = { 'file_name': file_name, 'file_size': file_size } header_json = json.dumps(header) header_bytes = header_json.encode('utf-8') header_size = struct.pack('i', len(header_bytes)) conn.send(header_size) conn.send(header_bytes) with open('%s/%s' % (service_path, file_name), 'rb') as f: for line in f: conn.send(line) def put(conn, cmd): pass def run(): file = socket.socket(socket.AF_INET, socket.SOCK_STREAM) file.bind(('127.0.0.1', 8912)) file.listen(5) while 1: print('wiating...') conn, addr = file.accept() while 1: cmd = conn.recv(1204).decode('utf-8').split() if not cmd: break print(cmd[0]) if cmd[0] == 'get': get(conn, cmd) conn.close() file.close() if __name__ == '__main__': run()
客户端
import socket import json import struct client_path = r'Y:py州_testTCP套接字通信套接字通信firstclient' def get(file, ret): file.send(ret.encode('utf-8')) header = file.recv(4) header_size = struct.unpack('i', header) header_info = file.recv(header_size[0]) header_json = json.loads(header_info) file_name = header_json['file_name'] file_size = header_json['file_size'] recv_size = 0 with open('%s/%s' % (client_path, file_name), 'wb') as f: while recv_size < file_size: ret = file.recv(1024) f.write(ret) recv_size += len(ret) print('传输大小:', recv_size) def put(file, ret): pass def run(): file = socket.socket(socket.AF_INET, socket.SOCK_STREAM) file.connect(('127.0.0.1', 8912)) while 1: ret = input('>>>').strip() if not ret: continue int = ret.split() if int[0] == 'get': get(file, ret) file.close() if __name__ == '__main__': run()
面向对象版
服务端
import socket import struct import json import os class Server: service_path = r'Y:py州_testTCP套接字通信套接字通信firstserveice' address_family = socket.AF_INET socket_type = socket.SOCK_STREAM max_packet_size = 8192 coding = 'utf-8' 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_listen() except: self.server_close() raise def server_bind(self): self.socket.bind(self.server_address) def server_listen(self): self.socket.listen(self.request_queue_size) def server_close(self): self.socket.close() def run(self): while True: print('wiating...') self.conn, self.addr = self.socket.accept() while True: print(self.addr) header = self.conn.recv(4) if not header: break header_len = struct.unpack('i', header)[0] header_json = self.conn.recv(header_len).decode(self.coding) header_dic = json.loads(header_json) cmd = header_dic['cmd'] if hasattr(self, cmd): func = getattr(self, cmd) func(header_dic) def put(self, header): file_name = header['file_name'] file_size = header['file_size'] file_path = os.path.normpath(os.path.join(self.service_path, file_name)) recv_size = 0 with open(file_path, 'wb') as f: while recv_size < file_size: ret = self.conn.recv(self.max_packet_size) f.write(ret) recv_size += len(ret) print("传输完成:", file_size) tcpserver = Server(('127.0.0.1', 8999)) tcpserver.run()
客户端
import socket import json import struct import os class Client: client_path = r'Y:py州_testTCP套接字通信套接字通信firstclient' address_family = socket.AF_INET socket_type = socket.SOCK_STREAM max_packet_size = 8192 coding = 'utf-8' def __init__(self, server_address, connect=True): self.server_address = server_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 run(self): cmd = input('>>>').strip() cmd_dic = cmd.split() cmds = cmd_dic[0] if hasattr(self, cmds): func = getattr(self, cmds) func(cmd_dic) def put(self, cmd): cmds = cmd[0] filename = cmd[1] if os.path.isfile(filename): filesize = os.path.getsize(filename) else: print('file:%s is not exists' % filename) return header_dic = { 'cmd': cmds, 'file_name': filename, 'file_size': filesize } header_json = json.dumps(header_dic) header_bytes = header_json.encode(self.coding) header_len = struct.pack('i', len(header_bytes)) self.socket.send(header_len) self.socket.send(header_bytes) send_len = 0 with open(filename, 'rb') as f: for line in f: self.socket.send(line) send_len += len(line) print(send_len) else: print('upload successful') client = Client(('127.0.0.1', 8999)) client.run()
udp协议
注意:udp协议不会发生粘包现象,每一次传输都是一个完整的报文;
如果 recvfrom(1024) 大于接收字符,直接完全接收且不会粘包第二次传输的内容。
如果 recvfrom(1024) 小于接收字符,则会丢失数据,数据不会缓存于通道中。
服务端
from socket import * server = socket(AF_INET, SOCK_DGRAM) server.bind(('127.0.0.1', 8099)) while 1: info, addr = server.recvfrom(1024) server.sendto(info.upper(),addr) server.close()
客户端
from socket import * client = socket(AF_INET, SOCK_DGRAM) while 1: inp = input('>>>').strip() client.sendto(inp.encode('utf-8'), ('127.0.0.1', 8099)) info, addr = client.recvfrom(1024) print(info) client.close()