中心思想: 传递过去文件的大小,根据文件的大小判断是否文件上传完成; 传递/接受文件采用分流的形式,每次传递/接受部分数据; 文件的读取均采用绝对路径实现,而且是bytes的形式读写
客户端:
# 客户端 import socket import os # family=AF_INET, 代表使用IPV4的IP协议 # type=SOCK_STREAM 代表使用TCP协议进行连接 client = socket.socket() ip_addr = ('127.0.0.1', 9999) BasePath = os.path.dirname(os.path.abspath(__file__)) while True: client.connect(ip_addr) inp = input('>>>:') # post | hhh.jpg cmd, path = inp.split('|') path = os.path.join(BasePath, path) filename = os.path.basename(path) file_size = os.stat(path).st_size file_info = '%s|%s|%s' % (cmd, filename, file_size) client.sendall(bytes(file_info, 'utf-8')) file_send = 0 with open(path, 'rb') as f: while file_send != file_size: data = f.read(1024) client.send(data) file_send += len(data) print('上传成功!') client.close() break client.close()
服务器端:
# 服务端 import socket import subprocess import os # family=AF_INET, 代表使用IPV4的IP协议 # type=SOCK_STREAM 代表使用TCP协议进行连接 server = socket.socket() # 创建socket ip_addr = ('127.0.0.1', 9999) # 1024之前的端口,默认是OS使用 server.bind(ip_addr) # 要求必须是一个元组 server.listen(3) # 开始监听传入连接。在拒绝连接之前,可以挂起的最大连接数量。 BasePath = os.path.dirname(os.path.abspath(__file__)) while True: conn, addr = server.accept() # 接受连接并返回(conn,address) # 其中conn是新的套接字对象[客户端],可以用来接收和发送数据。 # address是连接客户端的地址。 while 1: data = str(conn.recv(1024), 'utf-8') cmd, file_name, file_size = data.split('|') path = os.path.join(BasePath, 'hhh', file_name) file_size = int(file_size) rec_size = 0 with open(path, 'ab') as f: while rec_size != file_size: data = conn.recv(1024) rec_size += len(data) f.write(data) print('接受成功!') break conn.close() server.close()