单线程服务器、多线程服务器、异步服务器,三种架构实现大文件的发送和接收。
现在有单线程服务器的echo功能完成,试试看先把文件的读写功能做出来
path = './send/file2.txt' write_file = open(path,'w') write_string = '' for i in range(10000): write_string = write_string + str(i) if(i % 10 == 0): write_string = write_string + '\n' write_file.write(write_string) write_file.close()
注意:
1.文件路径,如果是在当前目录下的,记得路径开始的那个’.'别忘了
2.open文件的模式为‘w’,意思是先清空文件再写入,对于已经有内容的文件来说,这个操作是很危险的,注意小心
path = './send/file2.txt' write_file = open(path,'w') write_string = '' for i in range(100000000): write_string = write_string + str(i) if(len(write_string)>10000): write_file.write(write_string) write_string = '' write_file.write(write_string) write_file.close()
变体:生成更大的文件,如果生成长字符串保留在内存中的话,运行会非常慢,可以选择生成一段字符就写入文件一段,然后清空刚才保存在内存中的字符串,这样可以防止内存被占满导致无法继续写入。这样创建的文件大约770MB
def recv_and_write_until(sock,path): file = open(path,'w') message = sock.recv(4096) if not message: raise EOFError('socket closed') else: file.write(bytes_to_string(message)) if not message.endswith(SUFFIX): while True: data = sock.recv(4096) if not data: raise IOError('received {!r} then socket closed'.format(data)) if data.endswith(SUFFIX): file.write(bytes_to_string(data)) break else: file.write(bytes_to_string(data)) file.close()
同理,接收大文件的时候不能一次性全部收齐再写入,应该每收到一段就写入一次
def send_all_file(sock, path): MAX_LENGTH = 4000 file = open(path,'r') while True: block = file.read(MAX_LENGTH) if not block: sock.sendall(SUFFIX) break sock.sendall(block.encode('UTF-8'))
python 的read方法可以直接设置read多长(应该是多少个字节?)
看到有一种方法是用for line in file: 不过没试。测试的大文件包括整个文件只有一行的,不能用readline读,那样也会内存不够
到这里的话,文件读写工作算是完成了,可以用单线程服务器发送770MB大小的文件,下午来看不同的服务器架构