要求
客户端发送要下载的文件名给服务器,服务器将对应的文件内容送给客户端,客户端将文件存储到本地磁盘。
采用三种方法实现:
(1)单线程
(2)多线程
(3)异步方式(此处采用的是poll池)
思路
单线程:1、实现客户端和服务端的连接;2、在连接的基础上,用户发送文件名给服务器,服务器通过文件名打开可下载目录中的对应文件(此处可能会失败因此放在try中),成功匹配到以后发送固定头长度10b和文件二进制流的拼接字符串,否则发送0;3、客户端首先接收10b的内容,这就是文件的大小,为0表示文件不存在; 之后再循环不断接收固定长度MAX_BYTES的文件二进制流,保存到content二进制字符串中,直到全部接收成功再保存content(封帧操作) 。
多线程或者异步:在实现了单线程的代码上,将 可能造成阻塞的代码如IO操作等(此处则是传输文件二进制时会造成阻塞) 放在一个方法函数中,之后可以方便创建和调用多线程(异步)方法
源码
server1.py(单线程)
#实现单线程,迭代服务器(依次服务每一个客户端)
import socket
#限制最大传输速度
MAX_BYTES = 1024
tcp_server_host = ''
tcp_server_port = 8888
tcp_server_addr = (tcp_server_host ,tcp_server_port)
#成功找到文件返回文件长度+文件二进制流;失败返回0
def get_files_content(fileName ,tcp_client_addr):
try:
print('{}正在请求下载{}'.format(tcp_client_addr ,fileName))
with open('./files/' + fileName ,'rb') as fp:
file_content = fp.read()
#返回长度 + 二进制文件数据
return "{:010d}".format(len(file_content)).encode("utf-8") + file_content
except FileNotFoundError:
print('{}请求的{}未找到'.format(tcp_client_addr ,fileName))
return '0'.encode('utf-8')
#实现客户端和服务器交流
def communication(sock ,addr):
print('listen to {}'.