首先从顶部向下梳理,最顶上将文件持有(ResourceHolder)与用于请求者进行RMI调用的RMI服务器(即发送端)链接起来。
文件持有用于与注册中心进行连接等功能。
发送端用于等待请求者的调用。
调用即请求者发送给持有者 接受服务器地址及请求的资源:
首先有一个将资源持有者和对应资源发送者结合起来的ResourceHolderAndSender。这个类一个用于存储资源和资源持有者信息,这个类初始化时还开启了等待请求者请求资源的RMI服务器。
当用户利用RMI调用发送者的getContent方法:
public void getSendContent(ReceiverServerAddress receiverAddress,
ResourceFileSectionInfo resourceFileSectionInfo) {
RealSender realSender;
try {
realSender = new RealSender(receiverAddress,
resourceFileSectionInfo);
new Thread(realSender).start();
} catch (Exception e) {
e.printStackTrace();
}
}
创立针对该接收服务器及对应所被需求的文件片段的文件发送者。
realSender线程:
public void run() {
try {
ResourceHolder resourceHolder =
ResourceHolderAndSender.getResourceHolder();
if (resourceHolder == null) {
throw new Exception("ResourceHolder未准备!");
}
String resourceId = this.resourceFileSectionInfo.getResourceId();
this.resourceStructor = ResourceHolderAndSender.getResourceStructor(resourceId);
resourceHolder.resourceSendding();
String ip = this.receiverAddress.getIp();
int port = this.receiverAddress.getPort();
SendClient sendClient = new SendClient(
ip, port,
this.resourceStructor,
this.resourceFileSectionInfo, resourceHolder);
sendClient.connectToReceiveServer();
} catch (Exception e) {
e.printStackTrace();
}
}
这一段为发送做准备,建立sendClient,用于进行连接接收端的接收服务器,且开始发送。
对其所请求的资源生成FileSender,进行文件读取及发送
借助依据工程结构生成RandomAccessFilePool读取文件
此时涉及到两个新类,sectionReader和sectionSender
前者用于借助RandomAccessFilePool持续读取文件内容。
后者借助前者读取到的资源进行发送。
因为文件大分片按16M,而发送仅为32k,所以还需要监控发送进度。
整体文件发送完需要进行一个标记,这里使用发送一个不可能存在的文件片段,进行特殊标记。