资源篇

  • ResourceInfo
  • TransferDetail
  • FileInfo
  • FileHead

传统的客户端和服务端来说,客户端面对的是单一的服务器,
服务器及网络的带宽决定了网络的性能,每台服务器提供的信息数量,受到自身存储空间的限制,而任意时刻它所能支持的客户端的访问数量,则受到自身处理能力和网络带宽的限制,一旦服务器崩溃,整个网络也随之瘫痪。

对于服务器来说,当拥有大量的客户端进行访问的时候,服务器将承受巨大的压力。
对我们的多文件传输来说,我们的客户端想要请求某一数据资源的时候,我们只能访问单一的服务器,如果存在其他的客户端需要请求的资源和之前某一个客户端请求的资源相同,那么对于服务器来说,就需要再次进行响应相同的请求,那无疑对服务器来说是一种压力。

所以我的多文件自平衡云传输框架,有一个显著的特点,那就是当某个客户端在进行服务器请求的时候,最开始只有服务器有资源,当某个客户端拥有资源后,自己同样可以充当一个服务端,那么当再有客户端请求相同的资源的时候,那就会存在两个服务端可以进行资源的发送,以此类推,在出现了大量客户端的请求是时,对于真正的服务器来说,压力有一定的降低。

对于真正的服务器来说,首先向注册中心服务器进行资源的注册,告知注册资源自己的信息以及自己拥有的资源,当某个客户端向服务器请求资源时,服务端只是响应相关资源的一些基本的信息,而不会直接将真正的资源发送给客户端,此时客户端根据资源的基本信息,去向注册中心请求相关拥有该资源的节点列表,客户端根据返回的节点列表的信息,进行负载均衡挑选合适的能够发送资源的节点,进行链接这些节点,由这些节点服务器进行资源不同片段的发送。客户端根据一定的方案,将分散的资源进行整合。同时在接收到完整的资源之后,自已同样也可以作为一个发送端。

话不多说,先来看看整个框架最基础的部分,底层的传输和主要的基本资源信息的流动。
首先来说资源基本的信息,可谓是贯穿整个框架,客户端通过向服务器请求资源的资本信息,再根据基本信息进行可发送资源节点列表的获取。同样客户端可以根据依据资源的基本信息进行判断自己是否将资源接受完整,同时也是做为断点续传参考的依据。

ResourceInfo

public class ResourceInfo {//对应服务器要求的本地xml的路径,可根据不同个的服务器进行定义,通过读取配置文件的方式。 private static final String defultAppXml = "E:\\.KSGApp\\app.xml";private String resourceName;//资源的名称,简称private String root;//资源的相对路径private int version;private Map<Integer, FileInfo> fileInfoMap;//存储的是每个资源对应的多个文件的信息private List<FileHead> fileHeadList;//需要请求的文件的片段或者整个文件private xmlEditor xd;//用于将资源的资本信息保存到所请求的服务器默认的本地xml路径中。public ResourceInfo (ResourceInfo ri) {this.resourceName = ri.getResourceName();this.root = ri.getRoot();this.version = ri.getVersion();this.fileInfoMap = ri.getFileInfoMap();this.fileHeadList = ri.getFileHeadList();this.xd = ri.getXd();}public Map<Integer, FileInfo> getFileInfoMap() {return fileInfoMap;}public void setFileInfoMap(Map<Integer, FileInfo> fileInfoMap) {this.fileInfoMap = fileInfoMap;}public ResourceInfo() {fileInfoMap = new HashMap<Integer, FileInfo>();fileHeadList = new ArrayList<FileHead>();try {xd = new xmlEditor();} catch (ParserConfigurationException e) {e.printStackTrace();}}public FileInfo getFileInfo(int handle) {return fileInfoMap.get(handle);  }public static String getDefultAppXml() {return defultAppXml;}public void getAllFiles(Map<Integer, FileInfo> fileInfoMap) {//对于本地没有资源,直接将资源得全部文件进行请求//将map中的FileInfo变为,构造一个请求的listif(fileInfoMap == null) {return;}Set<Integer> keys = fileInfoMap.keySet();for(Integer one : keys) {FileInfo fi = fileInfoMap.get(one);FileHead fh = new FileHead();fh.setFileHandle(fi.getFileHandle());fh.setSectionLength((int)fi.getFileLength());fh.setOffset(0L);fileHeadList.add(fh);}}public void saveObject() {//通过getResource如果返回值为null,表明本地没有该资源//那么将设置本地root,并将资源存储在xml中//保存在本地不需要保存list和map,只需要保存基本的信息Map<Integer, FileInfo> tempMap = fileInfoMap;List<FileHead> tempList = fileHeadList;fileInfoMap = null;fileHeadList = null;xd.addObject(defultAppXml, this);fileInfoMap = tempMap;fileHeadList = tempList;} public ResourceInfo  getResoureFromXml() {//通过本地xml来查找,生成一个Object return (ResourceInfo)xd.getObject(defultAppXml, this.getClass(), "resourceName", resourceName);}public void addFileInfo(int hash, FileInfo fi) {//将资源的多个文件进行记录,每个文件的句柄采用的是文件的相对路径和文件的长度fileInfoMap.put(hash, fi); }public List<FileHead> getFileHeadList() {return fileHeadList;}public void setFileHeadList(List<FileHead> fileHeadList) {this.fileHeadList = fileHeadList;}
}

TransferDetail

用于字节流的传输,可通过设置传输中每次读取的字节数,

/** 用于底层数据的传输模块*/public class TransferDetail {//private static int signByte = 16;private ISendAndReceive Isa;public TransferDetail() {Isa = new SendAndReceive();}public ISendAndReceive getIsa() {return Isa;}/** 可通过设置进行ISendAndReceive的实现类的方案,主要是进行读数据方式的实现,* 可以调节读取的速率,设置每次进行读取的的字节的数量。*/public void setIsa(ISendAndReceive isa) {Isa = isa;}public byte[] readContentBytes(DataInputStream dis, int contentLength) throws IOException{return Isa.receive(dis, contentLength);}public byte[] readSignBytes(DataInputStream dis) throws IOException {return Isa.receive(dis, signByte);}public void writeBytes(DataOutputStream dos, byte[] bytes) {try {Isa.send(dos, bytes);        } catch (IOException e) {e.printStackTrace();}}
}

通过ResourceInfo中的成员我们能够看到有两个自定义类FileInfo和Filehead
这就要说到我们的底层传输的过程了,ResourceInfo这个类的对象通过在短连接的过程中进行传递,但客户端需要接收到真正的资源,而不仅仅是资源的一些资本信息,那么就需要FileInfo和Filehead来作为辅助。

FileInfo

/** 用来表示每个文件的信息* fileHandle 文件的句柄,用来确定文件的唯一性,值为其相对路径和文件长度的哈希值* fileRoot   文件的相对路径,对接收端来讲和发送单来讲可以确定本地存储的位置* fileLength 文件的长度大小,接收端可通过此判断一个文件文件是否完整。*/
public class FileInfo {private int fileHandle;private String fileRoot;private long fileLength;public FileInfo() {}public int getFileHandle() {return fileHandle;}public void setFileHandle(int fileHandle) {this.fileHandle = fileHandle;}public String getFileRoot() {return fileRoot;}public void setFileRoot(String fileRoot) {this.fileRoot = fileRoot;}public long getFileLength() {return fileLength;}public void setFileLength(long fileLength) {this.fileLength = fileLength;}@Overridepublic String toString() {return "FileInfo [fileHandle=" + fileHandle + ", fileRoot=" + fileRoot + ", fileLength=" + fileLength + "]";}
/*
*采用文件的长度和相对路径的hashcode作为文件的句柄,确定文件的唯一性
*/@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + (int) (fileLength ^ (fileLength >>> 32));result = prime * result + ((fileRoot == null) ? 0 : fileRoot.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;FileInfo other = (FileInfo) obj;if (fileLength != other.fileLength)return false;if (fileRoot == null) {if (other.fileRoot != null)return false;} else if (!fileRoot.equals(other.fileRoot))return false;return true;}
}

FileHead

在进行真正的资源传输的时候,底层的传输过程中,采用字节流的方式。此类在传输的时候转化为字节流,作为传输的标志信息由发送端先发送,发送端根据本类成员文件句柄,偏移量和长度在本地找到对应的文件片段片段进行再发送真正内容的字节流。对于接收端来说根据先发送的该类转化的字节流反转化为一个该类的对象,再根据对象成员的长度在流中读取相应的字节长度写入接收端本地。

/** 此类用来表示每个文件中的一个片段信息,当某个资源只拥有一个文件,并且此文件过大的* 话,我们要将一个文件进行分片。* 同样这个类是做为底层传输的一个重要的基础。* fileHandle    文件句柄,用来确定文件的唯一性* offset        片段处于文件的偏移量位置* sectionLength 片段的长度大小* **/
public class FileHead {private int fileHandle;private long offset;private int sectionLength;public FileHead() {     }public FileHead(byte[] value) {bytesToMember(value);}public FileHead(int fileHandle, long offset, int sectionLength) {this.fileHandle = fileHandle;this.offset = offset;this.sectionLength = sectionLength;}/**FIleHead表示的是文件的某个片段的信息,对于一个完整的文件来说,是由不同的fileHead进行组合*该方法用来判断某一片段是否为合理的文件片段**/public boolean ifRightHead(FileHead fh) {return fh.getOffset() >= this.offset && (this.offset + this.sectionLength)>= (fh.getOffset() + fh.getSectionLength());}/**将该对象转化为一个字节流*是发送端内部使用的方法,用于将片段信息进行转化发送*/public byte[] getHeadBytes() {byte[] bytes = new byte[16];byte[] intBOne = BytesThransefor.intToBytes(this.fileHandle);CombinBytes.produce(bytes, 0, intBOne);byte[] longB = BytesThransefor.longToBytes(this.offset);CombinBytes.produce(bytes, 4, longB);byte[] intBTwo = BytesThransefor.intToBytes(this.sectionLength);CombinBytes.produce(bytes, 12, intBTwo);return bytes;}/**将字节流转化为一个fileHead对象*在接收端内部进行给方法的调用,根据将字节流转化后成员的长度进行真正片段内容的读取。*/public FileHead bytesToMember(byte[] value) {//将一个字节流转化为成员byte[] intBOne = new byte[4];CombinBytes.dispose(value, 0, intBOne);this.fileHandle = BytesThransefor.bytesToInt(intBOne);byte[] longB = new byte[8];CombinBytes.dispose(value, 4, longB);this.offset = BytesThransefor.bytesToLong(longB);byte[] intBTwo = new byte[4];CombinBytes.dispose(value, 12, intBTwo);this.sectionLength = BytesThransefor.bytesToInt(intBTwo);return this;}public int getFileHandle() {return fileHandle;}public void setFileHandle(int fileHandle) {this.fileHandle = fileHandle;}public long getOffset() {return offset;}public void setOffset(long offset) {this.offset = offset;}public int getSectionLength() {return sectionLength;}public void setSectionLength(int sectionLength) {this.sectionLength = sectionLength;}@Overridepublic String toString() {return "(" + "fileHandle=" + fileHandle + ", offset=" + offset + ", sectionLength=" + sectionLength + ")" + "\n";}@Overridepublic int hashCode() {//采用fileHead的hashcode来进行    return fileHandle;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;FileHead other = (FileHead) obj;if (fileHandle != other.fileHandle)return false;return true;}
}

多文件自平衡云传输 (一) 资源篇 —————— 开开开山怪相关推荐

  1. 在线web免登陆云传输工具推荐【青蛙快传】

    一个比较好用的文件或者文本云传输工具,在线web版的,重要的是不需要登录,不需要登录,不需要登录! 优点1:无需登录,急速快传 优点2:手机电脑互传文件 优点3:不用安装软件,仅一个网址 青蛙快传 h ...

  2. [Java]分布式自平衡多文件云传输

    [Java]分布式自平衡多文件云传输 概述 基本思想 节点 Receiver接收方 资源分配及节点选择策略类 接收服务器端口池 资源请求类 短连接资源请求接口 资源信息类 资源节点关系表(资源管理中心 ...

  3. 电脑与云服务器传输文件,电脑与云服务器传输文件

    电脑与云服务器传输文件 内容精选 换一换 当创建文件系统后,您需要使用云服务器来挂载该文件系统,以实现多个云服务器共享使用文件系统的目的.本章节以Windows 2012版本操作系统为例进行CIFS类 ...

  4. 弹性服务器怎么上传文件,上传哪个文件夹弹性云服务器

    上传哪个文件夹弹性云服务器 内容精选 换一换 华为云帮助中心,为用户提供产品简介.价格说明.购买指南.用户指南.API参考.最佳实践.常见问题.视频帮助等技术文档,帮助您快速上手使用华为云服务. 本节 ...

  5. 读取云服务器文件列表,读取云服务器文件列表

    读取云服务器文件列表 内容精选 换一换 登录Windows操作系统的弹性云服务器时,需使用密码方式登录.因此,用户需先根据创建弹性云服务器时使用的密钥文件,获取该弹性云服务器初始安装时系统生成的管理员 ...

  6. 虚拟服务器传文件,虚拟机与主机传输文件

    虚拟机与主机传输文件 内容精选 换一换 云堡垒机支持文件传输功能,以及审计传输的文件.Linux主机和Windows主机的文件传输方式有所区别.Linux主机上传/下载文件,可选择Web运维和FTP/ ...

  7. 以“国土资源云”统领国土资源信息化建设

    以"国土资源云"统领国土资源信息化建设       2015-02-05 | 作者: 程秀娟 | 来源: 中国国土资源报 | [大中 小][打印][关闭]   1月26日,国土资源 ...

  8. 手机怎么向服务器传文件,手机向云服务器传文件

    手机向云服务器传文件 内容精选 换一换 登录Windows操作系统的弹性云服务器时,需要使用密码方式登录.此时,用户需要先根据购买弹性云服务器时下载的私钥文件,获取该弹性云服务器初始安装时系统生成的管 ...

  9. 手机 服务器文件,手机查看云服务器文件

    手机查看云服务器文件 内容精选 换一换 华为云帮助中心,为用户提供产品简介.价格说明.购买指南.用户指南.API参考.最佳实践.常见问题.视频帮助等技术文档,帮助您快速上手使用华为云服务. 密钥对鉴权 ...

  10. 云服务器怎么拷贝和删除文件,怎样给云服务器拷贝文件

    怎样给云服务器拷贝文件 内容精选 换一换 本章节主要介绍云硬盘.弹性文件服务.对象存储服务等存储服务,让您更好的了解这些存储服务. 云服务器备份:云服务器备份可以对普通服务器进行整机备份或部分磁盘备份 ...

最新文章

  1. 组合模式用于分类设计子叶与枝干时候太好用了
  2. MATLAB实战系列(一)-二维路径规划算法续集-图像边缘提取(附代码)
  3. 全排列问题pascal解题程序
  4. redhat安装wine教程_可能是最漂亮的国产Linux,U盘安装DeepinLinux 深度操作系统
  5. Codeforces 989C (构造)
  6. twitter api 无法连接_光大银行牟健君:金融API的安全问题和应对技术
  7. 华尔街弃儿:雷曼兄弟158岁被清算
  8. bottleneck resnet网络_深度学习|图像分类:ResNet(二)
  9. 编辑视频贴纸软件_视频特效编辑软件下载-视频特效编辑器下载V10.9.93-西西软件下载...
  10. 尽显中国风 | 高品质海报背景,PSD分层,智能替换展示商品
  11. 利用python gdal读写遥感影像
  12. 关于高德地图转换经纬度为屏幕点,方便自定义需链接网络的marker且添加属性动画
  13. FAT32文件系统格式详解
  14. 【Tool】CRC8 实现基础与原理解析
  15. SuperMap iDesktopX “电子地图坐标转换”—火星、百度坐标与常规坐标系之间的转换
  16. R导入excel数据
  17. C++ 20 std::chrono 库使用 | std::chrono::year_month_day |std::chrono::hh_mm_ss 使用
  18. Excel在数字单元格后面怎么添加统一的内容(数字或其他内容)
  19. TeamViewer14 ubuntu 破解商业环境
  20. 【转】91个排名:中国知名个人站长及发家史

热门文章

  1. java pfx 证书_java 证书 .cer 和 .pfx
  2. python数据分析设置教程视频_炼数成金女讲师Python数据分析实战应用视频教程
  3. 小程序接口加密时去除昵称数据含有的reshuffle表情(例如emoji)
  4. 满腔热诚永不忘,我以我血荐轩辕!
  5. EUI学习之DataGroup与List
  6. 洛谷—— P1419 寻找段落
  7. java 图文混排_图文混排的几种实现方案
  8. 2022中国智慧医疗领域最具商业合作价值企业盘点
  9. Sliced Sprite
  10. 送书6本,看谁答题快