mirror of
https://gitee.com/willfree/minoaClientWindows_gradle.git
synced 2026-10-05 01:15:44 +08:00
同步了这些天在CUTV客户端做的修改。
This commit is contained in:
1 parent
41d1a74acf
commit
dc40211f34
26 files changed
+1466
-327
No files matched your search
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
#commit changes: delete a prefix
|
||||
#Fri Apr 17 20:54:49 CST 2020
|
||||
Whitespace-only changes.
@@ -1,7 +1,7 @@
|
||||
#\u4FEE\u6539\u914D\u7F6E\u6587\u4EF6
|
||||
#Wed Apr 08 00:41:05 CST 2020
|
||||
KeyName=/testKey_v3
|
||||
loginUserName=466D1203678EFB16BE85C8A02E1486B6
|
||||
#Tue Apr 28 22:56:20 CST 2020
|
||||
KeyName=/王锋
|
||||
loginUserName=B94DF2C54EDEA80B50A94EA603DB833E
|
||||
ndnBlockChainIPAddress=116.77.74.139
|
||||
ServerIPAddress=116.77.74.139
|
||||
ThreadNumberForFileTransfer=5
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
@@ -1,12 +1,14 @@
|
||||
package cn.minoa;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import cn.minoa.dataRequestInterface.*;
|
||||
import cn.minoa.model.*;
|
||||
import cn.minoa.util.FileUtil;
|
||||
import cn.minoa.util.GenerateSettingFiles;
|
||||
import cn.minoa.util.LoggerUtil;
|
||||
import cn.minoa.util.StringByteLengthUtil;
|
||||
import cn.minoa.view.NavigationBarController;
|
||||
@@ -141,11 +143,19 @@ public class MainApp extends Application {
|
||||
private Stage uploadFileDialogStage;
|
||||
// 下载文件进度条stage
|
||||
private Stage downloadFileDialogStage;
|
||||
// 进度监听线程
|
||||
private Thread listenThread;
|
||||
// 上传客户端
|
||||
private UpLoadClientBPRenewal upLoadClient;
|
||||
// 下载客户端
|
||||
private DownLoadClientBPRenewal downLoadClient;
|
||||
|
||||
// 决定心跳包是否需要判断登录状态是否失效
|
||||
public boolean isNeedKnowLoginStatus=false;
|
||||
|
||||
public MainApp() {
|
||||
// 初始化ndn目录
|
||||
GenerateSettingFiles.generateInitFiles();
|
||||
// 加载配置文件
|
||||
loadSettingProperties();
|
||||
// 初始化一些数据
|
||||
@@ -200,8 +210,11 @@ public class MainApp extends Application {
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到配置文件...");
|
||||
}
|
||||
// 解决中文编码乱码问题
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(inputStream);
|
||||
// settingProperties.load(inputStream);
|
||||
settingProperties.load(bf);
|
||||
String serverIPAddress = settingProperties.getProperty("ServerIPAddress");
|
||||
String serverPortAddress = settingProperties.getProperty("ServerPortAddress");
|
||||
String NDNBlockChainIPAddressString=settingProperties.getProperty("ndnBlockChainIPAddress");
|
||||
@@ -426,6 +439,13 @@ public class MainApp extends Application {
|
||||
cancelButton.setOnAction(new EventHandler<ActionEvent>() {
|
||||
public void handle(ActionEvent event) {
|
||||
isCancelFileTransferFlag = true;
|
||||
// 再次关闭进度条监听线程
|
||||
listenThread.interrupt();
|
||||
// 保存断点信息
|
||||
downLoadClient.setPointInfo();
|
||||
// 关闭该次传输
|
||||
downLoadClient.closeSelf();
|
||||
// 弹窗关闭
|
||||
downloadFileDialogStage.close();
|
||||
}
|
||||
});
|
||||
@@ -446,10 +466,12 @@ public class MainApp extends Application {
|
||||
Long startTime = System.currentTimeMillis();
|
||||
// 滑动窗口协议下载文件
|
||||
// DownLoadClient downLoadClient = new DownLoadClient(filename,localDir,sliceNum);
|
||||
DownLoadClientBasedFacePool downLoadClient=new DownLoadClientBasedFacePool(filename,
|
||||
// DownLoadClientBasedFacePool downLoadClient=new DownLoadClientBasedFacePool(filename,
|
||||
// localDir,sliceNum,threadNumberForFileTransfer);
|
||||
downLoadClient=new DownLoadClientBPRenewal(filename,
|
||||
localDir,sliceNum,threadNumberForFileTransfer);
|
||||
//启动一个线程监听更新的传输进度值
|
||||
Thread listenThread = new Thread(new Runnable() {
|
||||
listenThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Long sliceNumLong=sliceNum.longValue();
|
||||
@@ -618,6 +640,13 @@ public class MainApp extends Application {
|
||||
public void handle(ActionEvent event) {
|
||||
// 手动取消了传输
|
||||
isCancelFileTransferFlag = true;
|
||||
// 再次关闭进度条监听线程
|
||||
listenThread.interrupt();
|
||||
// 上传信息保存到本地
|
||||
upLoadClient.setPointInfo();
|
||||
// 关闭该次传输
|
||||
upLoadClient.closeSelf();
|
||||
// 关闭弹窗
|
||||
uploadFileDialogStage.close();
|
||||
}
|
||||
});
|
||||
@@ -648,10 +677,14 @@ public class MainApp extends Application {
|
||||
Long startTime = System.currentTimeMillis();
|
||||
// 滑动窗口协议上传文件
|
||||
// UpLoadClient upLoadClient = new UpLoadClient(file, serverpath);
|
||||
UpLoadClientBasedFacePool upLoadClient=new UpLoadClientBasedFacePool(file,
|
||||
// 增加了facepool支持的滑动窗口协议
|
||||
// UpLoadClientBasedFacePool upLoadClient=new UpLoadClientBasedFacePool(file,
|
||||
// serverpath,threadNumberForFileTransfer);
|
||||
// 进一步增加了断点续传支持
|
||||
upLoadClient=new UpLoadClientBPRenewal(file,
|
||||
serverpath,threadNumberForFileTransfer);
|
||||
//启动一个线程监听更新的传输进度值
|
||||
Thread listenThread = new Thread(new Runnable() {
|
||||
listenThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
long filelen = file.length();
|
||||
@@ -707,6 +740,7 @@ public class MainApp extends Application {
|
||||
System.out.println("已成功将文件" + file.getAbsolutePath() + "上传至服务器" + serverpath + "目录下。");
|
||||
// String serverFilePath = serverpath + MinoaDataAPI.getPureFileNameFromWindows(file.getAbsolutePath());
|
||||
// ECOSUtil.sendUploadFileEndSignal(serverFilePath);
|
||||
// ECOSUtil.sendECOSUploadEndSignal(serverFilePath);
|
||||
} else {
|
||||
System.out.println("由于未知原因,本地文件" + file.getAbsolutePath() + "上传服务器失败。");
|
||||
}
|
||||
@@ -723,10 +757,10 @@ public class MainApp extends Application {
|
||||
public boolean uploadFileToServerSharedFolder(File file) {
|
||||
// Integer res=loginerController.sendFileToServer(file, this.sharedFileServerPath);
|
||||
Long startTime = System.currentTimeMillis();
|
||||
UpLoadClientBasedFacePool upLoadClient = new UpLoadClientBasedFacePool(
|
||||
UpLoadClientBPRenewal upLoadClient = new UpLoadClientBPRenewal(
|
||||
file,this.sharedFileServerPath,threadNumberForFileTransfer);
|
||||
// 下载文件
|
||||
boolean res = ((UpLoadClientBasedFacePool) upLoadClient).uploadData();
|
||||
boolean res = upLoadClient.uploadData();
|
||||
Long endTime = System.currentTimeMillis();
|
||||
System.out.println("耗时:" + (endTime - startTime) + "ms");
|
||||
return res;
|
||||
@@ -897,15 +931,17 @@ public class MainApp extends Application {
|
||||
// 判断是否是登录状态,且账号密码是正确的
|
||||
boolean m_flag=false;
|
||||
boolean isLoginning= KeepLoginStatus.getLogineStatus();
|
||||
Loginer m_loginer=KeepLoginStatus.getLoginerInfo();
|
||||
if((isLoginning==true)&&(m_loginer.getUserName()!=null)&&(m_loginer.getPassWord()!=null)){
|
||||
System.out.println("login status: "+isLoginning);
|
||||
System.out.println("loginer name: "+m_loginer.getUserName());
|
||||
System.out.println("loginer password: "+m_loginer.getPassWord());
|
||||
String loginString=loginerController.getLoginJsonString(
|
||||
m_loginer.getUserName(),m_loginer.getPassWord());
|
||||
if(loginerController.checkPass(loginString)){
|
||||
m_flag=true;
|
||||
if(isLoginning==true){
|
||||
Loginer m_loginer=KeepLoginStatus.getLoginerInfo();
|
||||
if((m_loginer.getUserName()!=null)&&(m_loginer.getPassWord()!=null)){
|
||||
System.out.println("login status: "+isLoginning);
|
||||
System.out.println("loginer name: "+m_loginer.getUserName());
|
||||
System.out.println("loginer password: "+m_loginer.getPassWord());
|
||||
String loginString=loginerController.getLoginJsonString(
|
||||
m_loginer.getUserName(),m_loginer.getPassWord());
|
||||
if(loginerController.checkPass(loginString)){
|
||||
m_flag=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -160,7 +160,8 @@ public class CongestionWindow {
|
||||
public void cwndDecrease(){
|
||||
synchronized (this){
|
||||
if(nIndata >= nSupress){
|
||||
this.thresh = Math.floor(this.cwnd/2);
|
||||
// this.thresh = Math.floor(this.cwnd/2);
|
||||
this.thresh = this.cwnd/2;
|
||||
this.cwnd = this.thresh;
|
||||
nSupress = (int)(nOutInterest + rate*(nOutInterest - nIndata));
|
||||
}
|
||||
|
||||
+212
-88
@@ -1,6 +1,8 @@
|
||||
package cn.minoa.dataRequestInterface;
|
||||
|
||||
import cn.minoa.MainApp;
|
||||
import cn.minoa.model.BPRInfo;
|
||||
import cn.minoa.util.FileBPRUtil;
|
||||
import net.named_data.jndn.*;
|
||||
import net.named_data.jndn.security.KeyChain;
|
||||
import net.named_data.jndn.security.SecurityException;
|
||||
@@ -20,7 +22,7 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
* @description
|
||||
* @date 2020-03-22 18:28
|
||||
*/
|
||||
public class DownLoadClientBasedFacePool {
|
||||
public class DownLoadClientBPRenewal {
|
||||
|
||||
// 下载前缀
|
||||
private String orderPrefix = "/downloadFile";
|
||||
@@ -51,13 +53,23 @@ public class DownLoadClientBasedFacePool {
|
||||
// 收到回复的数量
|
||||
public AtomicLong recvCount = new AtomicLong(0);
|
||||
|
||||
// 断点续传:此偏移量/序号之前的文件部分已经全部传输成功
|
||||
private AtomicLong successPoint=new AtomicLong(0);
|
||||
// 断点续传:point及其之后的兴趣包,已经传输成功的兴趣包序号
|
||||
private Map<Long, Boolean> successList = new ConcurrentHashMap<>();
|
||||
// 断点续传:当前文件哈希值
|
||||
private String fileHashString;
|
||||
|
||||
//发送的数据是否发送成功,key:第几个数据片,从0开始,value:该数据片超时次数
|
||||
private Map<Integer, Integer> timeOutNums = new ConcurrentHashMap<>();
|
||||
// 超时重传上限数值,某个兴趣包的重传次数超过此数值,则放弃重传,直接返回false
|
||||
private Integer timeoutCeil=15;
|
||||
|
||||
public DownLoadClientBasedFacePool(String filename, String localDir,
|
||||
Integer sliceNumber, Integer facepoolnumber) {
|
||||
// 标记该次传输是否关闭
|
||||
private boolean isClosed;
|
||||
|
||||
public DownLoadClientBPRenewal(String filename, String localDir,
|
||||
Integer sliceNumber, Integer facepoolnumber) {
|
||||
this.filename = filename;
|
||||
this.localDir = localDir;
|
||||
System.out.println("localDir: "+this.localDir);
|
||||
@@ -65,6 +77,59 @@ public class DownLoadClientBasedFacePool {
|
||||
this.facePool=new FacePool(facepoolnumber);
|
||||
this.facePool.start(MinoaDataAPI.minoaServerIpString, MinoaDataAPI.minoaServerPortInteger);
|
||||
System.out.println("***********FacePool中并发数:"+facepoolnumber+"***********");
|
||||
fileHashString=filename+"_"+sliceNumber;
|
||||
isClosed=false;
|
||||
}
|
||||
|
||||
/*
|
||||
* 传入一个刚被后台成功响应的兴趣包序号,
|
||||
* 判断[point,current]之间的兴趣包序号是否全部被成功响应
|
||||
*/
|
||||
private boolean isAllOK(Long point,Long currentNo){
|
||||
for(Long i=point;i<=currentNo;i++){
|
||||
if(!successList.containsKey(i)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 移除successList中已经成功发送的部分,减少内存占用
|
||||
private void mvSuccessNum(Long fromNo,Long toNo){
|
||||
for(Long i=fromNo;i<=toNo;i++){
|
||||
successList.remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
// 对每个成功收到200应答的兴趣包执行如下程序,
|
||||
// 以维持断点续传的功能
|
||||
private void refreshSuccessPoint(Long sliceNo){
|
||||
// 当前断点
|
||||
Long point=successPoint.get();
|
||||
// 加入successList
|
||||
successList.put(sliceNo,true);
|
||||
// 如果当前断点到新收到数据包之间的兴趣包全部成功响应,
|
||||
// 更新断点,并清理内存
|
||||
if(isAllOK(point,sliceNo)){
|
||||
successPoint.getAndSet(sliceNo+1);
|
||||
mvSuccessNum(point,sliceNo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 将本次传输的断点信息保存到本地
|
||||
public void setPointInfo(){
|
||||
String fileName= MinoaDataAPI.getPureFileName(filename);
|
||||
FileBPRUtil.setUploadBreakPointInfo(
|
||||
fileHashString,fileName,localDir,successPoint.get());
|
||||
System.out.println("保存断点信息成功!!!");
|
||||
}
|
||||
|
||||
// 移除已经上传成功的文件断点信息
|
||||
private void rmPointInfo(){
|
||||
if(FileBPRUtil.isHaveUploadBreakPointInfo(fileHashString)){
|
||||
FileBPRUtil.deleteUploadBreakPointInfo(fileHashString);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,6 +146,21 @@ public class DownLoadClientBasedFacePool {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 由于点击取消传输之后弹窗关闭,
|
||||
// 该文件类可能会继续发送数据,或有其它继续执行的代码
|
||||
// 这里增加一个函数进行关闭操作
|
||||
public void closeSelf(){
|
||||
try {
|
||||
this.randomAccessFile.close();
|
||||
System.out.println("本地文件关闭");
|
||||
} catch (IOException e) {
|
||||
System.out.println("取消传输时关闭文件报错:"+e.getMessage());
|
||||
}
|
||||
this.facePool.shutdownNow();
|
||||
this.isClosed=true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 下载数据的主函数
|
||||
*
|
||||
@@ -96,21 +176,45 @@ public class DownLoadClientBasedFacePool {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
while (true) {
|
||||
//判断是否已经上传安成
|
||||
// 判断是否有断点续传记录
|
||||
if(FileBPRUtil.isHaveUploadBreakPointInfo(fileHashString)){
|
||||
// 有记录,则判断文件名和服务器地址是否一致
|
||||
BPRInfo bprInfo=FileBPRUtil.getUploadBreakPointInfo(fileHashString);
|
||||
String fileName= MinoaDataAPI.getPureFileName(filename);
|
||||
if((!(bprInfo==null))
|
||||
&&bprInfo.getFileName().equals(fileName)
|
||||
&&bprInfo.getFileLocator().equals(localDir)){
|
||||
// 都一致,则更新recvCount\currentOffset\successPoint
|
||||
System.out.println("即将开始断点续传...");
|
||||
recvCount.getAndSet(bprInfo.getPoint());
|
||||
currentSliceNo=(int)recvCount.get();
|
||||
successPoint.getAndSet(bprInfo.getPoint());
|
||||
}else{
|
||||
System.out.println("即将开始文件下载...");
|
||||
}
|
||||
}else {
|
||||
System.out.println("即将开始文件下载...");
|
||||
}
|
||||
|
||||
while (!isClosed) {
|
||||
//判断是否已经下载完成
|
||||
if (recvCount.longValue()>=this.sliceNumber) {
|
||||
break;
|
||||
}
|
||||
|
||||
// 判断是否已经被用户终止上传
|
||||
// 判断是否已经被用户终止下载
|
||||
if(MainApp.isCancelFileTransferFlag){
|
||||
System.out.println("用户已主动中断下载");
|
||||
try {
|
||||
this.randomAccessFile.close();
|
||||
System.out.println("本地文件关闭");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// try {
|
||||
// this.randomAccessFile.close();
|
||||
// System.out.println("本地文件关闭");
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// this.facePool.shutdownNow();
|
||||
closeSelf();
|
||||
// 保存断点信息
|
||||
setPointInfo();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -143,25 +247,31 @@ public class DownLoadClientBasedFacePool {
|
||||
|
||||
if(isTimeOut()){
|
||||
System.out.println("丢包超过阈值: "+timeoutCeil+" ,文件传输主动中断");
|
||||
this.facePool.shutdownNow();
|
||||
try {
|
||||
this.randomAccessFile.close();
|
||||
System.out.println("本地文件关闭");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// try {
|
||||
// this.randomAccessFile.close();
|
||||
// System.out.println("本地文件关闭");
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// this.facePool.shutdownNow();
|
||||
closeSelf();
|
||||
// 保存断点信息
|
||||
setPointInfo();
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.facePool.shutdownNow();
|
||||
try {
|
||||
this.randomAccessFile.close();
|
||||
System.out.println("本地文件关闭");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// try {
|
||||
// this.randomAccessFile.close();
|
||||
// System.out.println("本地文件关闭");
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// this.facePool.shutdownNow();
|
||||
closeSelf();
|
||||
// 更新断点信息
|
||||
rmPointInfo();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -240,10 +350,11 @@ public class DownLoadClientBasedFacePool {
|
||||
|
||||
@Override
|
||||
public void onData(Interest interest, Data data) {
|
||||
// 将文件数据片写入本地文件
|
||||
try {
|
||||
synchronized (randomAccessFile) {
|
||||
System.out.println("开始写入文件数据分片... :" + localDir + localName);
|
||||
if(!isClosed) {
|
||||
// 将文件数据片写入本地文件
|
||||
try {
|
||||
synchronized (randomAccessFile) {
|
||||
System.out.println("开始写入文件数据分片... :" + localDir + localName);
|
||||
// RandomAccessFile randomAccessFile = new RandomAccessFile(localDir + localName, "rw");
|
||||
// int contentSize = data.getContent().size();
|
||||
// System.out.println("该数据分片长度为:" + contentSize);
|
||||
@@ -251,80 +362,93 @@ public class DownLoadClientBasedFacePool {
|
||||
// for (int i = 0; i < contentSize; i++) {
|
||||
// content[i] = data.getContent().buf().get(i);
|
||||
// }
|
||||
// 设置数据分片写入到文件的起点位置
|
||||
randomAccessFile.seek(sliceNo * MainApp.sliceSize);
|
||||
// 写入数据分片
|
||||
randomAccessFile.write(data.getContent().getImmutableArray());
|
||||
// 设置数据分片写入到文件的起点位置
|
||||
long offset=((long)sliceNo) * ((long) MainApp.sliceSize);
|
||||
try{
|
||||
randomAccessFile.seek(offset);
|
||||
}catch (IOException e){
|
||||
// 说明文件流已经关闭,则不继续执行
|
||||
return ;
|
||||
}
|
||||
// 写入数据分片
|
||||
randomAccessFile.write(data.getContent().getImmutableArray());
|
||||
// randomAccessFile.write(content, 0, contentSize);
|
||||
// randomAccessFile.close();
|
||||
System.out.println("写入文件数据分片完毕:" + localDir + localName);
|
||||
System.out.println("写入文件数据分片完毕:" + localDir + localName);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
|
||||
// 滑动窗口:flight--
|
||||
congestionWindow.inFlightDecrease();
|
||||
// 收到成功数据的数量++
|
||||
recvCount.incrementAndGet();
|
||||
// 滑动窗口:inData++
|
||||
congestionWindow.nIndataIncrease();
|
||||
// 刷新断点
|
||||
refreshSuccessPoint((long)sliceNo);
|
||||
System.out.println("第" + sliceNo + "片下载成功!");
|
||||
|
||||
// 处理拥塞:拥塞标记返回值,无意义,大于0就表示拥塞,直接进行窗口减小操作即可
|
||||
if (data.getCongestionMark() > 0) {
|
||||
System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&网络拥塞,滑动窗口减小,getCongestionMark:" + data.getCongestionMark());
|
||||
// 滑动窗口:cwndDecrease()
|
||||
congestionWindow.cwndDecrease();
|
||||
} else {
|
||||
// 滑动窗口:cwndIncrease()
|
||||
congestionWindow.cwndIncrease();
|
||||
}
|
||||
|
||||
if (timeOutNums.containsKey(this.sliceNo)) {
|
||||
timeOutNums.remove(this.sliceNo);
|
||||
}
|
||||
|
||||
// 处理完成
|
||||
isFinished = true;
|
||||
}
|
||||
|
||||
// 滑动窗口:flight--
|
||||
congestionWindow.inFlightDecrease();
|
||||
// 收到成功数据的数量++
|
||||
recvCount.incrementAndGet();
|
||||
// 滑动窗口:inData++
|
||||
congestionWindow.nIndataIncrease();
|
||||
System.out.println("第" + sliceNo + "片下载成功!");
|
||||
|
||||
// 处理拥塞:拥塞标记返回值,无意义,大于0就表示拥塞,直接进行窗口减小操作即可
|
||||
if (data.getCongestionMark() > 0) {
|
||||
System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&网络拥塞,滑动窗口减小,getCongestionMark:" + data.getCongestionMark());
|
||||
// 滑动窗口:cwndDecrease()
|
||||
congestionWindow.cwndDecrease();
|
||||
}else{
|
||||
// 滑动窗口:cwndIncrease()
|
||||
congestionWindow.cwndIncrease();
|
||||
}
|
||||
|
||||
if(timeOutNums.containsKey(this.sliceNo)){
|
||||
timeOutNums.remove(this.sliceNo);
|
||||
}
|
||||
|
||||
// 处理完成
|
||||
isFinished = true;
|
||||
}
|
||||
|
||||
// 处理兴趣包超时
|
||||
@Override
|
||||
public void onTimeout(Interest interest) {
|
||||
// 滑动窗口:flight--
|
||||
congestionWindow.inFlightDecrease();
|
||||
// 加入失败队列
|
||||
failedSlice.add(sliceNo);
|
||||
// 打印超时信息
|
||||
System.out.println("########## Time out for interest " + interest.getName()+"###########");
|
||||
if(!isClosed) {
|
||||
// 滑动窗口:flight--
|
||||
congestionWindow.inFlightDecrease();
|
||||
// 加入失败队列
|
||||
failedSlice.add(sliceNo);
|
||||
// 打印超时信息
|
||||
System.out.println("########## Time out for interest " + interest.getName() + "###########");
|
||||
|
||||
if(timeOutNums.containsKey(this.sliceNo)){
|
||||
int value = timeOutNums.get(this.sliceNo) + 1;
|
||||
timeOutNums.put(this.sliceNo,value);
|
||||
}else{
|
||||
timeOutNums.put(this.sliceNo,1);
|
||||
if (timeOutNums.containsKey(this.sliceNo)) {
|
||||
int value = timeOutNums.get(this.sliceNo) + 1;
|
||||
timeOutNums.put(this.sliceNo, value);
|
||||
} else {
|
||||
timeOutNums.put(this.sliceNo, 1);
|
||||
}
|
||||
// 处理完成
|
||||
isFinished = true;
|
||||
}
|
||||
// 处理完成
|
||||
isFinished = true;
|
||||
}
|
||||
|
||||
// 处理收到一个Nack包
|
||||
@Override
|
||||
public void onNetworkNack(Interest interest, NetworkNack networkNack){
|
||||
congestionWindow.inFlightDecrease();
|
||||
failedSlice.add(sliceNo);
|
||||
if(timeOutNums.containsKey(this.sliceNo)){
|
||||
int value = timeOutNums.get(this.sliceNo) + 1;
|
||||
timeOutNums.put(this.sliceNo,value);
|
||||
}else{
|
||||
timeOutNums.put(this.sliceNo,1);
|
||||
public void onNetworkNack(Interest interest, NetworkNack networkNack) {
|
||||
if (!isClosed) {
|
||||
congestionWindow.inFlightDecrease();
|
||||
failedSlice.add(sliceNo);
|
||||
if (timeOutNums.containsKey(this.sliceNo)) {
|
||||
int value = timeOutNums.get(this.sliceNo) + 1;
|
||||
timeOutNums.put(this.sliceNo, value);
|
||||
} else {
|
||||
timeOutNums.put(this.sliceNo, 1);
|
||||
}
|
||||
// 打印超时信息
|
||||
System.out.println("########## Nack for interest " + interest.getName()
|
||||
+ ", Nack: " + networkNack.toString());
|
||||
isFinished = true;
|
||||
}
|
||||
// 打印超时信息
|
||||
System.out.println("########## Nack for interest " + interest.getName()
|
||||
+", Nack: "+networkNack.toString());
|
||||
isFinished=true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,14 @@ package cn.minoa.dataRequestInterface;
|
||||
|
||||
import net.named_data.jndn.Name;
|
||||
import net.named_data.jndn.security.KeyChain;
|
||||
import net.named_data.jndn.security.pib.Pib;
|
||||
import net.named_data.jndn.security.pib.PibIdentity;
|
||||
import net.named_data.jndn.security.pib.PibImpl;
|
||||
import net.named_data.jndn.security.pib.PibSqlite3;
|
||||
import net.named_data.jndn.security.pib.*;
|
||||
import net.named_data.jndn.security.tpm.Tpm;
|
||||
import net.named_data.jndn.security.tpm.TpmBackEnd;
|
||||
import net.named_data.jndn.security.tpm.TpmBackEndFile;
|
||||
import net.named_data.jndn.security.v2.CertificateV2;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public enum KeyManager {
|
||||
INSTANCE;
|
||||
private KeyChain keyChain = null;
|
||||
@@ -42,8 +41,10 @@ public enum KeyManager {
|
||||
private KeyChain getOrBuildKeyChain(String identityName) throws
|
||||
KeyChain.Error, PibImpl.Error, Pib.Error, Tpm.Error, TpmBackEnd.Error, CertificateV2.Error {
|
||||
KeyChain keyChain = null;
|
||||
PibSqlite3 pibSqlite3 = new PibSqlite3("./ndn/pid");
|
||||
TpmBackEndFile tpmBackEndFile = new TpmBackEndFile("./ndn/tpm");
|
||||
PibSqlite3 pibSqlite3=new PibSqlite3("." + File.separator + "ndn"+
|
||||
File.separator+"pid");
|
||||
TpmBackEndFile tpmBackEndFile = new TpmBackEndFile("." + File.separator + "ndn"+
|
||||
File.separator+"tpm");
|
||||
try {
|
||||
keyChain = new KeyChain(pibSqlite3, tpmBackEndFile);
|
||||
PibIdentity identity = keyChain.getPib().getIdentity(new Name(identityName));
|
||||
@@ -63,8 +64,10 @@ public enum KeyManager {
|
||||
public boolean isInKeyChain(String identityName) throws
|
||||
KeyChain.Error, PibImpl.Error, Pib.Error, Tpm.Error, TpmBackEnd.Error, CertificateV2.Error {
|
||||
KeyChain keyChain = null;
|
||||
PibSqlite3 pibSqlite3 = new PibSqlite3("./ndn/pid");
|
||||
TpmBackEndFile tpmBackEndFile = new TpmBackEndFile("./ndn/tpm");
|
||||
PibSqlite3 pibSqlite3=new PibSqlite3("." + File.separator + "ndn"+
|
||||
File.separator+"pid");
|
||||
TpmBackEndFile tpmBackEndFile = new TpmBackEndFile("." + File.separator + "ndn"+
|
||||
File.separator+"tpm");
|
||||
try {
|
||||
keyChain = new KeyChain(pibSqlite3, tpmBackEndFile);
|
||||
PibIdentity identity = keyChain.getPib().getIdentity(new Name(identityName));
|
||||
|
||||
+207
-82
@@ -1,6 +1,9 @@
|
||||
package cn.minoa.dataRequestInterface;
|
||||
|
||||
// 在原来基于FacePool上传文件的基础上,
|
||||
// 增加断点续传功能
|
||||
import cn.minoa.MainApp;
|
||||
import cn.minoa.model.BPRInfo;
|
||||
import cn.minoa.util.FileBPRUtil;
|
||||
import cn.minoa.util.StringByteLengthUtil;
|
||||
import net.named_data.jndn.*;
|
||||
import net.named_data.jndn.security.KeyChain;
|
||||
@@ -24,7 +27,7 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
* @description
|
||||
* @date 2020-03-22 18:28
|
||||
*/
|
||||
public class UpLoadClientBasedFacePool {
|
||||
public class UpLoadClientBPRenewal {
|
||||
|
||||
private String orderPrefix = "/uploadFile";
|
||||
|
||||
@@ -49,24 +52,104 @@ public class UpLoadClientBasedFacePool {
|
||||
private ConcurrentLinkedQueue<Long> failedSlice = new ConcurrentLinkedQueue<>();
|
||||
|
||||
//发送的数据是否发送成功,key:第几个数据片,从0开始,value:是否发送成功
|
||||
private Map<Long, Boolean> sendRes = new ConcurrentHashMap<>();
|
||||
// private Map<Long, Boolean> sendRes = new ConcurrentHashMap<>();
|
||||
|
||||
//收到回复的数量
|
||||
public AtomicLong recvCount = new AtomicLong(0);
|
||||
|
||||
// 断点续传:此偏移量/序号之前的文件部分已经全部传输成功
|
||||
private AtomicLong successPoint=new AtomicLong(0);
|
||||
// 断点续传:point及其之后的兴趣包,已经传输成功的兴趣包序号
|
||||
private Map<Long, Boolean> successList = new ConcurrentHashMap<>();
|
||||
// 断点续传:当前文件哈希值
|
||||
private String fileHashString;
|
||||
|
||||
//发送的数据是否发送成功,key:第几个数据片,从0开始,value:该数据片超时次数
|
||||
private Map<Long, Integer> timeOutNums = new ConcurrentHashMap<>();
|
||||
// 超时重传上限数值,某个兴趣包的重传次数超过此数值,则放弃重传,直接返回false
|
||||
private Integer timeoutCeil=15;
|
||||
|
||||
public UpLoadClientBasedFacePool(File file, String serverPath, Integer facepoolnumber){
|
||||
// 标记该次传输的状态
|
||||
private boolean isClosed;
|
||||
|
||||
public UpLoadClientBPRenewal(File file, String serverPath, Integer facepoolnumber){
|
||||
this.file = file;
|
||||
this.serverPath = serverPath;
|
||||
this.facePool=new FacePool(facepoolnumber);
|
||||
this.facePool.start(MinoaDataAPI.minoaServerIpString, MinoaDataAPI.minoaServerPortInteger);
|
||||
System.out.println("***********FacePool中并发数:"+facepoolnumber+"***********");
|
||||
// fileHashString= EncryptionUtil.getFileHash(file.getAbsolutePath());
|
||||
fileHashString= MinoaDataAPI.getPureFileNameFromWindows(file.getAbsolutePath())
|
||||
+"_"+file.length();
|
||||
isClosed=false;
|
||||
}
|
||||
|
||||
// 由于点击取消传输之后弹窗关闭,
|
||||
// 该文件类可能会继续发送数据,或有其它继续执行的代码
|
||||
// 这里增加一个函数进行关闭操作
|
||||
public void closeSelf(){
|
||||
try {
|
||||
this.randomAccessFile.close();
|
||||
System.out.println("本地文件关闭");
|
||||
} catch (IOException e) {
|
||||
System.out.println("取消传输时关闭文件报错:"+e.getMessage());
|
||||
}
|
||||
this.facePool.shutdownNow();
|
||||
this.isClosed=true;
|
||||
}
|
||||
|
||||
/*
|
||||
* 传入一个刚被后台成功响应的兴趣包序号,
|
||||
* 判断[point,current]之间的兴趣包序号是否全部被成功响应
|
||||
*/
|
||||
private boolean isAllOK(Long point,Long currentNo){
|
||||
for(Long i=point;i<=currentNo;i++){
|
||||
if(!successList.containsKey(i)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 移除successList中已经成功发送的部分,减少内存占用
|
||||
private void mvSuccessNum(Long fromNo,Long toNo){
|
||||
for(Long i=fromNo;i<=toNo;i++){
|
||||
successList.remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
// 对每个成功收到200应答的兴趣包执行如下程序,
|
||||
// 以维持断点续传的功能
|
||||
private void refreshSuccessPoint(Long sliceNo){
|
||||
// 当前断点
|
||||
Long point=successPoint.get();
|
||||
// 加入successList
|
||||
successList.put(sliceNo,true);
|
||||
// 如果当前断点到新收到数据包之间的兴趣包全部成功响应,
|
||||
// 更新断点,并清理内存
|
||||
if(isAllOK(point,sliceNo)){
|
||||
successPoint.getAndSet(sliceNo+1);
|
||||
mvSuccessNum(point,sliceNo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 将本次传输的断点信息保存到本地
|
||||
public void setPointInfo(){
|
||||
String fileName= MinoaDataAPI.getPureFileNameFromWindows(file.getAbsolutePath());
|
||||
FileBPRUtil.setUploadBreakPointInfo(
|
||||
fileHashString,fileName,serverPath,successPoint.get());
|
||||
System.out.println("保存断点信息成功!!!");
|
||||
}
|
||||
|
||||
// 移除已经上传成功的文件断点信息
|
||||
private void rmPointInfo(){
|
||||
if(FileBPRUtil.isHaveUploadBreakPointInfo(fileHashString)){
|
||||
FileBPRUtil.deleteUploadBreakPointInfo(fileHashString);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断是否含有超时次数超过阈值的
|
||||
* @return
|
||||
@@ -94,14 +177,35 @@ public class UpLoadClientBasedFacePool {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// 初始化sliceNumbers
|
||||
if(file.length()% MainApp.sliceSize == 0){
|
||||
sliceNumbers = file.length()/ MainApp.sliceSize;
|
||||
}else{
|
||||
sliceNumbers = file.length()/ MainApp.sliceSize + 1;
|
||||
}
|
||||
|
||||
while(true){
|
||||
//判断是否已经上传安成
|
||||
// 判断是否有断点续传记录
|
||||
if(FileBPRUtil.isHaveUploadBreakPointInfo(fileHashString)){
|
||||
// 有记录,则判断文件名和服务器地址是否一致
|
||||
BPRInfo bprInfo=FileBPRUtil.getUploadBreakPointInfo(fileHashString);
|
||||
String fileName= MinoaDataAPI.getPureFileNameFromWindows(file.getAbsolutePath());
|
||||
if((!(bprInfo==null))
|
||||
&&bprInfo.getFileName().equals(fileName)
|
||||
&&bprInfo.getFileLocator().equals(serverPath)){
|
||||
// 都一致,则更新recvCount\currentOffset\successPoint
|
||||
System.out.println("即将开始断点续传...");
|
||||
recvCount.getAndSet(bprInfo.getPoint());
|
||||
currentOffset=recvCount.get()* MainApp.sliceSize;
|
||||
successPoint.getAndSet(bprInfo.getPoint());
|
||||
}else{
|
||||
System.out.println("即将开始文件上传...");
|
||||
}
|
||||
}else {
|
||||
System.out.println("即将开始文件上传...");
|
||||
}
|
||||
|
||||
while(!isClosed){
|
||||
// 判断是否已经上传完成
|
||||
if(sliceNumbers <= recvCount.longValue()){
|
||||
break;
|
||||
}
|
||||
@@ -109,12 +213,16 @@ public class UpLoadClientBasedFacePool {
|
||||
// 判断是否已经被用户终止上传
|
||||
if(MainApp.isCancelFileTransferFlag){
|
||||
System.out.println("用户已主动中断上传");
|
||||
try {
|
||||
this.randomAccessFile.close();
|
||||
System.out.println("本地文件关闭");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// try {
|
||||
// this.randomAccessFile.close();
|
||||
// System.out.println("本地文件关闭");
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// this.facePool.shutdownNow();
|
||||
closeSelf();
|
||||
// 保存断点信息
|
||||
setPointInfo();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -145,30 +253,35 @@ public class UpLoadClientBasedFacePool {
|
||||
}
|
||||
congestionWindow.inFlightIncrease();
|
||||
congestionWindow.nOutInterestIncrease();
|
||||
|
||||
}
|
||||
|
||||
if(isTimeOut()){
|
||||
System.out.println("丢包超过阈值: "+timeoutCeil+" ,文件传输主动中断");
|
||||
this.facePool.shutdownNow();
|
||||
try {
|
||||
this.randomAccessFile.close();
|
||||
System.out.println("本地文件关闭");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// try {
|
||||
// this.randomAccessFile.close();
|
||||
// System.out.println("本地文件关闭");
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// this.facePool.shutdownNow();
|
||||
closeSelf();
|
||||
// 保存断点信息
|
||||
setPointInfo();
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
this.randomAccessFile.close();
|
||||
System.out.println("本地文件关闭");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.facePool.shutdownNow();
|
||||
// try {
|
||||
// this.randomAccessFile.close();
|
||||
// System.out.println("本地文件关闭");
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// this.facePool.shutdownNow();
|
||||
closeSelf();
|
||||
// 更新本地断点信息
|
||||
rmPointInfo();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -224,7 +337,12 @@ public class UpLoadClientBasedFacePool {
|
||||
synchronized (randomAccessFile) {
|
||||
// RandomAccessFile randomAccessFile = new RandomAccessFile(localFilePath, "rw");
|
||||
// 设置文件的读取起点
|
||||
randomAccessFile.seek(offset);
|
||||
try{
|
||||
randomAccessFile.seek(offset);
|
||||
}catch (IOException e){
|
||||
// 说明文件流已经关闭,则不继续执行
|
||||
return ;
|
||||
}
|
||||
// 尝试读取数据
|
||||
int readLen = randomAccessFile.read(content, 0, 7000);
|
||||
int jsonLen = StringByteLengthUtil.getByteLength(orderInfo.getJsonString());
|
||||
@@ -296,41 +414,44 @@ public class UpLoadClientBasedFacePool {
|
||||
|
||||
@Override
|
||||
public void onData(Interest interest, Data data){
|
||||
responseData.setResponseData(data.getContent().toString());
|
||||
JSONObject jsonObject = responseData.praseRequestData();
|
||||
if (!isClosed) {
|
||||
responseData.setResponseData(data.getContent().toString());
|
||||
JSONObject jsonObject = responseData.praseRequestData();
|
||||
|
||||
congestionWindow.inFlightDecrease();
|
||||
// 解析数据,是否成功上传
|
||||
Integer codeInteger = null;
|
||||
try {
|
||||
codeInteger = jsonObject.getInt("code");
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (codeInteger == 200) {
|
||||
recvCount.incrementAndGet();
|
||||
congestionWindow.cwndIncrease();
|
||||
System.out.println("第" + sliceNum + "片上传成功!");
|
||||
}else{
|
||||
failedSlice.add(sliceNum* MainApp.sliceSize);
|
||||
System.out.println("第" + sliceNum + "片上传失败!");
|
||||
}
|
||||
//拥塞标记返回值,无意义,大于0就表示拥塞,直接进行窗口减小操作即可
|
||||
if(data.getCongestionMark() > 0){
|
||||
System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&网络拥塞,滑动窗口减小,getCongestionMark:" + data.getCongestionMark());
|
||||
congestionWindow.cwndDecrease();
|
||||
}else{
|
||||
//如果没有检测到拥塞,则增加窗口
|
||||
congestionWindow.nIndataIncrease();
|
||||
}
|
||||
congestionWindow.inFlightDecrease();
|
||||
// 解析数据,是否成功上传
|
||||
Integer codeInteger = null;
|
||||
try {
|
||||
codeInteger = jsonObject.getInt("code");
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (codeInteger == 200) {
|
||||
recvCount.incrementAndGet();
|
||||
congestionWindow.cwndIncrease();
|
||||
// 刷新断点
|
||||
refreshSuccessPoint(sliceNum);
|
||||
System.out.println("第" + sliceNum + "片上传成功!");
|
||||
} else {
|
||||
failedSlice.add(sliceNum * MainApp.sliceSize);
|
||||
System.out.println("第" + sliceNum + "片上传失败!");
|
||||
}
|
||||
//拥塞标记返回值,无意义,大于0就表示拥塞,直接进行窗口减小操作即可
|
||||
if (data.getCongestionMark() > 0) {
|
||||
System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&网络拥塞,滑动窗口减小,getCongestionMark:" + data.getCongestionMark());
|
||||
congestionWindow.cwndDecrease();
|
||||
} else {
|
||||
//如果没有检测到拥塞,则增加窗口
|
||||
congestionWindow.nIndataIncrease();
|
||||
}
|
||||
|
||||
if(timeOutNums.containsKey(sliceNum)){
|
||||
timeOutNums.remove(sliceNum);
|
||||
if (timeOutNums.containsKey(sliceNum)) {
|
||||
timeOutNums.remove(sliceNum);
|
||||
}
|
||||
|
||||
isFinished = true;
|
||||
}
|
||||
|
||||
isFinished = true;
|
||||
|
||||
}
|
||||
public int callbackCount = 0 ;
|
||||
|
||||
@@ -349,18 +470,20 @@ public class UpLoadClientBasedFacePool {
|
||||
|
||||
@Override
|
||||
public void onTimeout(Interest interest){
|
||||
congestionWindow.inFlightDecrease();
|
||||
failedSlice.add(upLoadData.sliceNum* MainApp.sliceSize);
|
||||
callbackCount ++ ;
|
||||
System.out.println("Time out for interest " + interest.getName());
|
||||
upLoadData.isFinished = false;
|
||||
if (!isClosed) {
|
||||
congestionWindow.inFlightDecrease();
|
||||
failedSlice.add(upLoadData.sliceNum * MainApp.sliceSize);
|
||||
callbackCount++;
|
||||
System.out.println("Time out for interest " + interest.getName());
|
||||
upLoadData.isFinished = false;
|
||||
|
||||
//
|
||||
if(timeOutNums.containsKey(upLoadData.sliceNum)){
|
||||
int value = timeOutNums.get(upLoadData.sliceNum) + 1;
|
||||
timeOutNums.put(upLoadData.sliceNum,value);
|
||||
}else{
|
||||
timeOutNums.put(upLoadData.sliceNum,1);
|
||||
//
|
||||
if (timeOutNums.containsKey(upLoadData.sliceNum)) {
|
||||
int value = timeOutNums.get(upLoadData.sliceNum) + 1;
|
||||
timeOutNums.put(upLoadData.sliceNum, value);
|
||||
} else {
|
||||
timeOutNums.put(upLoadData.sliceNum, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -376,18 +499,20 @@ public class UpLoadClientBasedFacePool {
|
||||
|
||||
@Override
|
||||
public void onNetworkNack(Interest var1, NetworkNack var2){
|
||||
congestionWindow.inFlightDecrease();
|
||||
failedSlice.add(upLoadData.sliceNum* MainApp.sliceSize);
|
||||
//
|
||||
if(timeOutNums.containsKey(upLoadData.sliceNum)){
|
||||
int value = timeOutNums.get(upLoadData.sliceNum) + 1;
|
||||
timeOutNums.put(upLoadData.sliceNum,value);
|
||||
}else{
|
||||
timeOutNums.put(upLoadData.sliceNum,1);
|
||||
if (!isClosed) {
|
||||
congestionWindow.inFlightDecrease();
|
||||
failedSlice.add(upLoadData.sliceNum * MainApp.sliceSize);
|
||||
//
|
||||
if (timeOutNums.containsKey(upLoadData.sliceNum)) {
|
||||
int value = timeOutNums.get(upLoadData.sliceNum) + 1;
|
||||
timeOutNums.put(upLoadData.sliceNum, value);
|
||||
} else {
|
||||
timeOutNums.put(upLoadData.sliceNum, 1);
|
||||
}
|
||||
callbackCount++;
|
||||
System.out.println("onNetworkNack " + var1.getName());
|
||||
upLoadData.isFinished = true;
|
||||
}
|
||||
callbackCount ++ ;
|
||||
System.out.println("onNetworkNack " + var1.getName());
|
||||
upLoadData.isFinished = true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package cn.minoa.model;
|
||||
// 断点续传中,需要持久化到本地的文件参数
|
||||
|
||||
public class BPRInfo {
|
||||
|
||||
// 文件唯一标识:上传中指的是哈希值,下载中指的是文件服务器URL
|
||||
// 现在上传和下载的该数值全部定义为:纯文件名_文件长度
|
||||
private String fileId;
|
||||
// 文件名称
|
||||
private String fileName;
|
||||
// 文件位置:上传中指的是文件服务器位置,下载中指的是文件本地位置
|
||||
private String fileLocator;
|
||||
// 断点续传位置
|
||||
private Long point;
|
||||
|
||||
public BPRInfo(){
|
||||
}
|
||||
|
||||
public String getFileId() {
|
||||
return fileId;
|
||||
}
|
||||
|
||||
public void setFileId(String fileId) {
|
||||
this.fileId = fileId;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
public String getFileLocator() {
|
||||
return fileLocator;
|
||||
}
|
||||
|
||||
public void setFileLocator(String fileLocator) {
|
||||
this.fileLocator = fileLocator;
|
||||
}
|
||||
|
||||
public Long getPoint() {
|
||||
return point;
|
||||
}
|
||||
|
||||
public void setPoint(Long point) {
|
||||
this.point = point;
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,45 @@
|
||||
package cn.minoa.util;
|
||||
|
||||
//import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
public class EncryptionUtil {
|
||||
// 获取文件md5加密结果
|
||||
// public static String getFileHash(String path){
|
||||
// Long startTime = System.currentTimeMillis();
|
||||
// // File
|
||||
//// String path="E:\\系统镜像\\ubuntu-18.04.3-desktop-amd64.iso";
|
||||
//// String path="E:\\系统镜像\\UltraISO.9.7.0.3476.exe";
|
||||
// String res=null;
|
||||
// try {
|
||||
// res= DigestUtils.md5Hex(new FileInputStream(path));
|
||||
// System.out.println("文件"+path+"加密结果:"+res);
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// Long endTime=System.currentTimeMillis();
|
||||
// System.out.println("文件"+path+"加密耗时:"+(endTime-startTime)+"ms");
|
||||
// return res;
|
||||
// }
|
||||
|
||||
public static String getMD5String(String str) {
|
||||
str= URLEncoder.encode(str, StandardCharsets.UTF_8);
|
||||
try {
|
||||
// 生成一个MD5加密计算摘要
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
// 计算md5函数
|
||||
md.update(str.getBytes("utf-8"));
|
||||
md.update(str.getBytes(StandardCharsets.UTF_8));
|
||||
// digest()最后确定返回md5 hash值,返回值为8位字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符
|
||||
// BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值
|
||||
//一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方)
|
||||
@@ -30,6 +53,7 @@ public class EncryptionUtil {
|
||||
}
|
||||
|
||||
public static String encryptBasedAES(String content) {
|
||||
// content= URLEncoder.encode(content, StandardCharsets.UTF_8);
|
||||
byte[] encrypt=encryptBasedAES(content,"123");
|
||||
return ParseSystemUtil.parseByte2HexStr(encrypt);
|
||||
}
|
||||
@@ -46,18 +70,20 @@ public class EncryptionUtil {
|
||||
* @return 密文
|
||||
*/
|
||||
public static byte[] encryptBasedAES(String content, String password) {
|
||||
// content= URLEncoder.encode(content, StandardCharsets.UTF_8);
|
||||
// password= URLEncoder.encode(password, StandardCharsets.UTF_8);
|
||||
try {
|
||||
KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者
|
||||
// kgen.init(128, new SecureRandom(password.getBytes()));// 利用用户密码作为随机数初始化出
|
||||
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
|
||||
secureRandom.setSeed(password.getBytes("utf-8"));
|
||||
secureRandom.setSeed(password.getBytes(StandardCharsets.UTF_8));
|
||||
kgen.init(128, secureRandom);
|
||||
//加密没关系,SecureRandom是生成安全随机数序列,password.getBytes()是种子,只要种子相同,序列就一样,所以解密只要有password就行
|
||||
SecretKey secretKey = kgen.generateKey();// 根据用户密码,生成一个密钥
|
||||
byte[] enCodeFormat = secretKey.getEncoded();// 返回基本编码格式的密钥,如果此密钥不支持编码,则返回
|
||||
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 转换为AES专用密钥
|
||||
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
|
||||
byte[] byteContent = content.getBytes("utf-8");
|
||||
byte[] byteContent = content.getBytes(StandardCharsets.UTF_8);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化为加密模式的密码器
|
||||
byte[] result = cipher.doFinal(byteContent);// 加密
|
||||
return result;
|
||||
@@ -65,8 +91,6 @@ public class EncryptionUtil {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
@@ -78,13 +102,11 @@ public class EncryptionUtil {
|
||||
}
|
||||
|
||||
public static String decryptBasedAES(String hexStr) {
|
||||
// hexStr= URLEncoder.encode(hexStr, StandardCharsets.UTF_8);
|
||||
byte[] byte2 = ParseSystemUtil.parseHexStr2Byte(hexStr);
|
||||
try {
|
||||
return new String(decryptBasedAES(byte2, "123"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
String s=new String(decryptBasedAES(byte2, "123"),StandardCharsets.UTF_8);
|
||||
// s=URLEncoder.encode(s,StandardCharsets.UTF_8);
|
||||
return s;
|
||||
}
|
||||
|
||||
// public static byte[] decryptBasedAES(byte[] content) {
|
||||
@@ -98,12 +120,13 @@ public class EncryptionUtil {
|
||||
* @param password 加密时的密码
|
||||
* @return 明文
|
||||
*/
|
||||
public static byte[] decryptBasedAES(byte[] content, String password) throws UnsupportedEncodingException {
|
||||
public static byte[] decryptBasedAES(byte[] content, String password){
|
||||
// password=URLEncoder.encode(password,StandardCharsets.UTF_8);
|
||||
try {
|
||||
KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者
|
||||
// kgen.init(128, new SecureRandom(password.getBytes()));
|
||||
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
|
||||
secureRandom.setSeed(password.getBytes("utf-8"));
|
||||
secureRandom.setSeed(password.getBytes(StandardCharsets.UTF_8));
|
||||
kgen.init(128, secureRandom);
|
||||
SecretKey secretKey = kgen.generateKey();// 根据用户密码,生成一个密钥
|
||||
byte[] enCodeFormat = secretKey.getEncoded();// 返回基本编码格式的密钥
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
package cn.minoa.util;
|
||||
|
||||
import cn.minoa.model.BPRInfo;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Properties;
|
||||
|
||||
// 文件断点续传支持类
|
||||
// 功能:存储和移除传输失败的文件信息
|
||||
public class FileBPRUtil {
|
||||
|
||||
// 判断某md5哈希值是否在本地存储条目中
|
||||
public static boolean isHaveUploadBreakPointInfo(String hashString) {
|
||||
// 加密
|
||||
hashString= EncryptionUtil.encryptBasedAES(hashString);
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream = new BufferedInputStream(new FileInputStream("." + File.separator + "ndn" + File.separator + "FileBPRenewal.properties"));
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到断点续传配置文件...");
|
||||
return false;
|
||||
}
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(bf);
|
||||
String filename=settingProperties.getProperty("fileName-"+hashString);
|
||||
System.out.println(hashString+" : "+filename);
|
||||
if(filename==null){
|
||||
return false;
|
||||
}else{
|
||||
System.out.println("本地存在该文件的断点信息:"+hashString);
|
||||
return true;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
return false;
|
||||
} finally {
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// public static boolean isHaveDownloadBreakPointInfo(String fileUrlString) {
|
||||
// return isHaveUploadBreakPointInfo(fileUrlString);
|
||||
// }
|
||||
|
||||
|
||||
// 存储上传文件断点信息到本地
|
||||
public static void setUploadBreakPointInfo(String hashString,
|
||||
String pureFileName,
|
||||
String serverPath,
|
||||
Long point){
|
||||
// 加密
|
||||
hashString= EncryptionUtil.encryptBasedAES(hashString);
|
||||
pureFileName= EncryptionUtil.encryptBasedAES(pureFileName);
|
||||
serverPath= EncryptionUtil.encryptBasedAES(serverPath);
|
||||
String pointString= EncryptionUtil.encryptBasedAES(point.toString());
|
||||
InputStream inputStream = null;
|
||||
OutputStream outputStream=null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream=new BufferedInputStream(new FileInputStream("."+ File.separator+"ndn"+File.separator+"FileBPRenewal.properties"));
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到断点续传配置文件...");
|
||||
}
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(bf);
|
||||
settingProperties.setProperty("fileName-"+hashString, pureFileName);
|
||||
settingProperties.setProperty("fileServerPath-"+hashString,serverPath);
|
||||
settingProperties.setProperty("filePoint-"+hashString, pointString);
|
||||
outputStream=new BufferedOutputStream(new FileOutputStream("."+ File.separator+"ndn"+File.separator+"FileBPRenewal.properties"));
|
||||
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(outputStream,StandardCharsets.UTF_8));
|
||||
settingProperties.store(bw,"commit changes");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}finally{
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//关闭输出流
|
||||
if (outputStream != null) {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 移除上传文件的断点信息
|
||||
public static void deleteUploadBreakPointInfo(String hashString){
|
||||
// 加密
|
||||
hashString= EncryptionUtil.encryptBasedAES(hashString);
|
||||
InputStream inputStream = null;
|
||||
OutputStream outputStream=null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream=new BufferedInputStream(new FileInputStream("."+ File.separator+"ndn"+File.separator+"FileBPRenewal.properties"));
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到断点续传配置文件...");
|
||||
}
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(bf);
|
||||
settingProperties.remove("fileName-"+hashString);
|
||||
settingProperties.remove("fileServerPath-"+hashString);
|
||||
settingProperties.remove("filePoint-"+hashString);
|
||||
outputStream=new BufferedOutputStream(new FileOutputStream("."+ File.separator+"ndn"+File.separator+"FileBPRenewal.properties"));
|
||||
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(outputStream,StandardCharsets.UTF_8));
|
||||
settingProperties.store(bw,"commit changes");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}finally{
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//关闭输出流
|
||||
if (outputStream != null) {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// public static void setDownloadBreakPointInfo(String fileUrlString,
|
||||
// String pureFileName,
|
||||
// String localPath,
|
||||
// Long point){
|
||||
// setUploadBreakPointInfo(fileUrlString,pureFileName,localPath,point);
|
||||
// }
|
||||
//
|
||||
// public static void deleteDownloadBreakPointInfo(String fileUrlString){
|
||||
// deleteUploadBreakPointInfo(fileUrlString);
|
||||
// }
|
||||
|
||||
// 取出上传文件断点信息到本地
|
||||
public static BPRInfo getUploadBreakPointInfo(String hashString) {
|
||||
// 加密
|
||||
hashString= EncryptionUtil.encryptBasedAES(hashString);
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream = new BufferedInputStream(new FileInputStream("." + File.separator + "ndn" + File.separator + "FileBPRenewal.properties"));
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到断点续传配置文件...");
|
||||
}
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(bf);
|
||||
BPRInfo bprInfo=new BPRInfo();
|
||||
bprInfo.setFileId(hashString);
|
||||
bprInfo.setFileName(EncryptionUtil.decryptBasedAES(settingProperties.getProperty("fileName-"+hashString)));
|
||||
bprInfo.setFileLocator(EncryptionUtil.decryptBasedAES(settingProperties.getProperty("fileServerPath-"+hashString)));
|
||||
bprInfo.setPoint(Long.parseLong(EncryptionUtil.decryptBasedAES(settingProperties.getProperty("filePoint-"+hashString))));
|
||||
System.out.println("util-文件名:"+bprInfo.getFileName());
|
||||
System.out.println("util-文件断点:"+bprInfo.getPoint());
|
||||
System.out.println("util-文件路径:"+bprInfo.getFileLocator());
|
||||
if((bprInfo.getFileName()==null)||(bprInfo.getPoint()==null)||(bprInfo.getFileLocator()==null)){
|
||||
return null;
|
||||
}
|
||||
return bprInfo;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// public static BPRInfo getDownloadBreakPointInfo(String fileUrlString) {
|
||||
// return getUploadBreakPointInfo(fileUrlString);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
//1. 上传文件
|
||||
// 1.1 如果上传成功,且该次上传是续传,则移除该文件哈希值对应的本地存储条目;
|
||||
// 1.2 如果上传失败,则将文件断点信息存到本地:md5哈希值、纯文件名、服务器路径、断点
|
||||
// 1.3 每次上传文件,都要计算一下md5哈希值,然后查表,看本地有没有这个哈希值。
|
||||
// 如果有,就取文件名、要传的服务器路径,对比一下,全部都对的上,就从断点位置继续传该文件;如果没该哈希值,或文件名、路径不一致,则从0开始上传。
|
||||
//
|
||||
//2. 下载文件
|
||||
// 2.1 如果下载成功,且该次下载是续传,则移除该次下载的文件对应的服务器url所对应的本地存储条目;
|
||||
// 2.2 如果下载失败,则将文件断点信息保存到本地:文件对应的服务器url(如:/a/b.txt)、纯文件名、本地目录、断点
|
||||
// 2.3 每次下载文件,都查看要下载的文件的服务器url是否在本地存储中。如果在,就取纯文件名、本地目录对比一下,如果全部都对的上,就从断点位置继续传该文件;如果没该服务器url,或文件名、路径不一致,则从0开始下载。
|
||||
//3. 问题:
|
||||
// 1. 由于上述断点全部存储在客户端,那么对于电脑突然死机或用户直接关闭客户端的情况,是无法将断点信息保存到本地的,也就无法续传;
|
||||
// 2. 上述下载中,所谓文件服务器URL,并不是文件唯一标识,如果出现文件错判,续传之后的文件将可能是两个不同文件的结合体。
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
package cn.minoa.util;
|
||||
// 生成配置文件
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Properties;
|
||||
|
||||
public class GenerateSettingFiles {
|
||||
|
||||
public static void generateInitFiles(){
|
||||
generateNDNDir();
|
||||
generateSettingFile();
|
||||
generateBPRFile();
|
||||
generateNDNBlockFile();
|
||||
}
|
||||
|
||||
public static void generateNDNDir(){
|
||||
String path="." + File.separator + "ndn";
|
||||
File file=new File(path);
|
||||
if(!file.exists()&&!file.isDirectory()){
|
||||
file.mkdir();
|
||||
System.out.println("ndn目录创建成功");
|
||||
}else{
|
||||
System.out.println("ndn目录已经存在");
|
||||
}
|
||||
}
|
||||
|
||||
public static void generateNDNBlockFile() {
|
||||
String path = "." + File.separator + "ndn" + File.separator +"BlockSuccessUsers.properties";
|
||||
generateNDNBlockFile(path);
|
||||
}
|
||||
|
||||
public static void generateNDNBlockFile(String path) {
|
||||
File file = new File(path);
|
||||
// 创建配置文件
|
||||
if (!file.exists()) {
|
||||
try {
|
||||
file.createNewFile();
|
||||
System.out.println("区块链注册信息文件创建成功");
|
||||
} catch (IOException e) {
|
||||
System.out.println("区块链注册信息文件创建失败:" + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
System.out.println(path + "区块链注册信息文件已经存在");
|
||||
}
|
||||
}
|
||||
|
||||
public static void generateBPRFile() {
|
||||
String path = "." + File.separator + "ndn" + File.separator +"FileBPRenewal.properties";
|
||||
generateBPRFiles(path);
|
||||
}
|
||||
|
||||
public static void generateBPRFiles(String path) {
|
||||
File file = new File(path);
|
||||
// 创建配置文件
|
||||
if (!file.exists()) {
|
||||
try {
|
||||
file.createNewFile();
|
||||
System.out.println("断点信息记录文件创建成功");
|
||||
} catch (IOException e) {
|
||||
System.out.println("断点信息记录文件创建失败:" + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
System.out.println(path + "断点信息记录文件已经存在");
|
||||
}
|
||||
}
|
||||
|
||||
public static void generateSettingFile() {
|
||||
String path = "." + File.separator + "ndn" + File.separator + "settings.properties";
|
||||
generateSettingFile(path);
|
||||
}
|
||||
|
||||
public static void generateSettingFile(String path) {
|
||||
File file = new File(path);
|
||||
boolean isNew=false; //标志配置文件是否是新建的
|
||||
// 创建配置文件
|
||||
if (!file.exists()) {
|
||||
isNew=true;
|
||||
try {
|
||||
file.createNewFile();
|
||||
System.out.println("setting配置文件创建成功");
|
||||
} catch (IOException e) {
|
||||
System.out.println("setting配置文件创建失败:" + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
isNew=false;
|
||||
System.out.println(path + "配置文件已经存在");
|
||||
}
|
||||
// 如果是新建配置文件,则写入配置文件的默认内容
|
||||
if(isNew) {
|
||||
InputStream inputStream = null;
|
||||
OutputStream outputStream = null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream = new BufferedInputStream(new FileInputStream(path));
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到配置文件...");
|
||||
}
|
||||
// 解决中文乱码问题
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(bf);
|
||||
settingProperties.setProperty("ServerIPAddress", "116.77.74.139");
|
||||
settingProperties.setProperty("ServerPortAddress", "6363");
|
||||
settingProperties.setProperty("ndnBlockChainIPAddress", "116.77.74.139");
|
||||
settingProperties.setProperty("ndnBlockChainPortAddress", "9001");
|
||||
settingProperties.setProperty("DataPackagePrefix", "/ndn/edu/pkusz/OA");
|
||||
settingProperties.setProperty("ThreadNumberForFileTransfer", "5");
|
||||
settingProperties.setProperty("KeyName", "/default");
|
||||
settingProperties.setProperty("LoginStatus", "false");
|
||||
settingProperties.setProperty("loginUserName", "default");
|
||||
settingProperties.setProperty("loginPassWord", "default");
|
||||
outputStream = new BufferedOutputStream(new FileOutputStream(path));
|
||||
// 解决中文乱码问题
|
||||
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
|
||||
settingProperties.store(bw, "初始化配置文件");
|
||||
System.out.println("setting配置文件内容初始化成功");
|
||||
} catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
System.out.println("setting配置文件内容填充失败" + e.getMessage());
|
||||
} finally {
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//关闭输出流
|
||||
if (outputStream != null) {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
System.out.println(path+"配置文件内容保持不变");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package cn.minoa.util;
|
||||
import cn.minoa.MainApp;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Properties;
|
||||
|
||||
public class KeyStorageUtil {
|
||||
@@ -17,11 +18,13 @@ public class KeyStorageUtil {
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到配置文件...");
|
||||
}
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(inputStream);
|
||||
settingProperties.load(bf);
|
||||
settingProperties.setProperty("KeyName", keyName);
|
||||
outputStream=new BufferedOutputStream(new FileOutputStream(MainApp.getClientPath()+ File.separator+"ndn"+File.separator+"settings.properties"));
|
||||
settingProperties.store(outputStream,"修改配置文件");
|
||||
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(outputStream,StandardCharsets.UTF_8));
|
||||
settingProperties.store(bw,"修改配置文件");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}finally{
|
||||
@@ -49,13 +52,15 @@ public class KeyStorageUtil {
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream = new BufferedInputStream(new FileInputStream(MainApp.getClientPath() + File.separator + "ndn" + File.separator + "settings.properties"));
|
||||
inputStream = new BufferedInputStream(new FileInputStream("." + File.separator + "ndn" + File.separator +
|
||||
"settings.properties"));
|
||||
// inputStream = MainApp.class.getClassLoader().getResourceAsStream("/ndn/settings.properties");
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到配置文件...");
|
||||
}
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(inputStream);
|
||||
settingProperties.load(bf);
|
||||
String keyName = settingProperties.getProperty("KeyName");
|
||||
return keyName;
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -9,7 +9,8 @@ public class LoggerUtil {
|
||||
// 将文件名、文件操作、传输耗时等信息写入日志.
|
||||
public static void insertFileAction(String filename, String fileaction, String usedtime) {
|
||||
try {
|
||||
File file = new File("./ndn/log.txt");
|
||||
File file = new File("." + File.separator + "ndn" +
|
||||
File.separator +"log.txt");
|
||||
FileOutputStream fos = null;
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();//如果文件不存在,就创建该文件
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
package cn.minoa.util;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Properties;
|
||||
|
||||
public class RegisterUtil {
|
||||
// 用户记录:通过了区块链注册,但是没有通过后台注册的用户前缀
|
||||
|
||||
public static boolean isAccessedBlockUser(String prefix) {
|
||||
// 加密
|
||||
String hashString= EncryptionUtil.encryptBasedAES(prefix);
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream = new BufferedInputStream(new FileInputStream("." + File.separator + "ndn" + File.separator + "BlockSuccessUsers.properties"));
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(bf);
|
||||
String filename=settingProperties.getProperty(hashString);
|
||||
System.out.println(hashString+" : "+filename);
|
||||
if(filename==null){
|
||||
return false;
|
||||
}else{
|
||||
System.out.println("本地存在该文件的断点信息:"+hashString);
|
||||
return true;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
return false;
|
||||
} finally {
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void setAccessedBlockUser(String prefix){
|
||||
// 加密
|
||||
String hashString= EncryptionUtil.encryptBasedAES(prefix);
|
||||
InputStream inputStream = null;
|
||||
OutputStream outputStream=null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream=new BufferedInputStream(new FileInputStream("."+ File.separator+"ndn"+File.separator+"BlockSuccessUsers.properties"));
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(bf);
|
||||
settingProperties.setProperty(hashString, hashString);
|
||||
outputStream=new BufferedOutputStream(new FileOutputStream("."+ File.separator+"ndn"+File.separator+"BlockSuccessUsers.properties"));
|
||||
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(outputStream,StandardCharsets.UTF_8));
|
||||
settingProperties.store(bw,"commit changes: add a prefix");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}finally{
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//关闭输出流
|
||||
if (outputStream != null) {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void deleteAccessedBlockUser(String prefix){
|
||||
// 加密
|
||||
String hashString= EncryptionUtil.encryptBasedAES(prefix);
|
||||
InputStream inputStream = null;
|
||||
OutputStream outputStream=null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream=new BufferedInputStream(new FileInputStream("."+ File.separator+"ndn"+File.separator+"BlockSuccessUsers.properties"));
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(bf);
|
||||
settingProperties.remove(hashString);
|
||||
outputStream=new BufferedOutputStream(new FileOutputStream("."+ File.separator+"ndn"+File.separator+"BlockSuccessUsers.properties"));
|
||||
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(outputStream,StandardCharsets.UTF_8));
|
||||
settingProperties.store(bw,"commit changes: delete a prefix");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}finally{
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//关闭输出流
|
||||
if (outputStream != null) {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
package cn.minoa.view.home;
|
||||
|
||||
import cn.minoa.MainApp;
|
||||
import cn.minoa.dataRequestInterface.DownLoadClientBasedFacePool;
|
||||
import cn.minoa.dataRequestInterface.DownLoadClientBPRenewal;
|
||||
import cn.minoa.dataRequestInterface.OrderInfo;
|
||||
import cn.minoa.dataRequestInterface.ResponseData;
|
||||
import cn.minoa.model.Email;
|
||||
import cn.minoa.model.Reimbursement;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Alert;
|
||||
@@ -14,14 +13,11 @@ import javafx.scene.layout.Pane;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.stage.Stage;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class DealSingleReimbursementController {
|
||||
private MainApp mainApp;
|
||||
@@ -126,7 +122,7 @@ public class DealSingleReimbursementController {
|
||||
sliceNum++;
|
||||
}
|
||||
Long startTime = System.currentTimeMillis();
|
||||
DownLoadClientBasedFacePool downLoadClient = new DownLoadClientBasedFacePool(pathfilename,
|
||||
DownLoadClientBPRenewal downLoadClient = new DownLoadClientBPRenewal(pathfilename,
|
||||
localDirString,sliceNum,mainApp.threadNumberForFileTransfer);
|
||||
// 下载文件
|
||||
boolean res = downLoadClient.downloadData();
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package cn.minoa.view.home;
|
||||
|
||||
import cn.minoa.MainApp;
|
||||
import cn.minoa.dataRequestInterface.DownLoadClientBasedFacePool;
|
||||
import cn.minoa.dataRequestInterface.DownLoadClientBPRenewal;
|
||||
import cn.minoa.model.Reimbursement;
|
||||
import cn.minoa.view.login.LoginOverviewController;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.ListView;
|
||||
@@ -115,7 +114,7 @@ public class SingleReimbursementDetailsController {
|
||||
sliceNum++;
|
||||
}
|
||||
Long startTime = System.currentTimeMillis();
|
||||
DownLoadClientBasedFacePool downLoadClient = new DownLoadClientBasedFacePool(pathfilename,
|
||||
DownLoadClientBPRenewal downLoadClient = new DownLoadClientBPRenewal(pathfilename,
|
||||
localDirString,sliceNum,mainApp.threadNumberForFileTransfer);
|
||||
// 下载文件
|
||||
boolean res = downLoadClient.downloadData();
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package cn.minoa.view.login;
|
||||
|
||||
import cn.minoa.Main;
|
||||
import cn.minoa.MainApp;
|
||||
import cn.minoa.model.Loginer;
|
||||
import cn.minoa.util.EncryptionUtil;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Properties;
|
||||
|
||||
// 维持长登录状态
|
||||
@@ -19,15 +21,17 @@ public class KeepLoginStatus {
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到配置文件...");
|
||||
}
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(inputStream);
|
||||
settingProperties.load(bf);
|
||||
if(flag==true){
|
||||
settingProperties.setProperty("LoginStatus","true");
|
||||
}else{
|
||||
settingProperties.setProperty("LoginStatus","false");
|
||||
}
|
||||
outputStream=new BufferedOutputStream(new FileOutputStream(MainApp.getClientPath()+ File.separator+"ndn"+File.separator+"settings.properties"));
|
||||
settingProperties.store(outputStream,"修改配置文件");
|
||||
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(outputStream,StandardCharsets.UTF_8));
|
||||
settingProperties.store(bw,"修改配置文件");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}finally{
|
||||
@@ -59,12 +63,14 @@ public class KeepLoginStatus {
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到配置文件...");
|
||||
}
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(inputStream);
|
||||
settingProperties.setProperty("loginUserName", EncryptionUtil.encryptBasedAES(loginer.getUserName()));
|
||||
settingProperties.setProperty("loginPassWord", EncryptionUtil.encryptBasedAES(loginer.getPassWord()));
|
||||
settingProperties.load(bf);
|
||||
settingProperties.setProperty("loginUserName",EncryptionUtil.encryptBasedAES(loginer.getUserName()));
|
||||
settingProperties.setProperty("loginPassWord",EncryptionUtil.encryptBasedAES(loginer.getPassWord()));
|
||||
outputStream=new BufferedOutputStream(new FileOutputStream(MainApp.getClientPath()+ File.separator+"ndn"+File.separator+"settings.properties"));
|
||||
settingProperties.store(outputStream,"修改配置文件");
|
||||
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(outputStream,StandardCharsets.UTF_8));
|
||||
settingProperties.store(bw,"修改配置文件");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}finally{
|
||||
@@ -97,8 +103,9 @@ public class KeepLoginStatus {
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到配置文件...");
|
||||
}
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(inputStream);
|
||||
settingProperties.load(bf);
|
||||
String username = EncryptionUtil.decryptBasedAES(settingProperties.getProperty("loginUserName"));
|
||||
String password = EncryptionUtil.decryptBasedAES(settingProperties.getProperty("loginPassWord"));
|
||||
// System.out.println("username: " + username);
|
||||
@@ -129,8 +136,9 @@ public class KeepLoginStatus {
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到配置文件...");
|
||||
}
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(inputStream);
|
||||
settingProperties.load(bf);
|
||||
String LoginStatus = settingProperties.getProperty("LoginStatus");
|
||||
if(LoginStatus.equals("true")){
|
||||
return true;
|
||||
|
||||
@@ -453,7 +453,7 @@ public class LoginOverviewController {
|
||||
// 获取用户列表信息
|
||||
ResponseData responseData = mainApp.minoaDataAPI.dataCacheQueue.getResponseDataBySeq(seqLong);
|
||||
JSONObject jsonObject = responseData.praseRequestData();
|
||||
// System.out.println("getUsers-JSON: "+jsonObject.toString());
|
||||
System.out.println("getUsers-JSON: "+jsonObject.toString());
|
||||
Integer codeInteger = null;
|
||||
try {
|
||||
codeInteger = jsonObject.getInt("code");
|
||||
@@ -1004,7 +1004,7 @@ public class LoginOverviewController {
|
||||
sliceNum++;
|
||||
}
|
||||
Long startTime = System.currentTimeMillis();
|
||||
DownLoadClientBasedFacePool downLoadClient = new DownLoadClientBasedFacePool(filename,
|
||||
DownLoadClientBPRenewal downLoadClient = new DownLoadClientBPRenewal(filename,
|
||||
localDir,sliceNum,mainApp.threadNumberForFileTransfer);
|
||||
// 下载文件
|
||||
boolean res = downLoadClient.downloadData();
|
||||
|
||||
@@ -2,11 +2,27 @@ package cn.minoa.view.login;
|
||||
// 与区块链建立TCP连接,发送注册请求
|
||||
|
||||
import cn.minoa.MainApp;
|
||||
import cn.minoa.dataRequestInterface.KeyManager;
|
||||
import net.named_data.jndn.Name;
|
||||
import net.named_data.jndn.Signature;
|
||||
import net.named_data.jndn.encoding.der.DerDecodingException;
|
||||
import net.named_data.jndn.security.KeyChain;
|
||||
import net.named_data.jndn.security.SecurityException;
|
||||
import net.named_data.jndn.security.SigningInfo;
|
||||
import net.named_data.jndn.security.pib.PibImpl;
|
||||
import net.named_data.jndn.security.tpm.TpmBackEnd;
|
||||
import net.named_data.jndn.security.v2.CertificateV2;
|
||||
import net.named_data.jndn.util.Blob;
|
||||
import net.named_data.jndn.util.Common;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.Socket;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.Security;
|
||||
import java.security.cert.Certificate;
|
||||
|
||||
public class NDNBlockChainConnectClient {
|
||||
|
||||
@@ -14,20 +30,77 @@ public class NDNBlockChainConnectClient {
|
||||
private Integer NDNBlockChainPortAddress;
|
||||
|
||||
public NDNBlockChainConnectClient(){
|
||||
// this.NDNBlockChainIPAddress="116.77.74.144";
|
||||
// this.NDNBlockChainIPAddress="121.15.171.86";
|
||||
// this.NDNBlockChainPortAddress=8010;
|
||||
this.NDNBlockChainIPAddress= MainApp.NDNBlockChainIPAddress;
|
||||
System.out.println("区块链IP:"+ MainApp.NDNBlockChainIPAddress);
|
||||
this.NDNBlockChainPortAddress= MainApp.NDNBlockChainPortAddress;
|
||||
System.out.println("区块链Port:"+ MainApp.NDNBlockChainPortAddress);
|
||||
System.out.println("区块链IP:"+MainApp.NDNBlockChainIPAddress);
|
||||
this.NDNBlockChainPortAddress=MainApp.NDNBlockChainPortAddress;
|
||||
System.out.println("区块链Port:"+MainApp.NDNBlockChainPortAddress);
|
||||
}
|
||||
|
||||
public NDNBlockChainConnectClient(String ipAddress, Integer portAddress){
|
||||
public NDNBlockChainConnectClient(String ipAddress,Integer portAddress){
|
||||
this.NDNBlockChainIPAddress= ipAddress;
|
||||
this.NDNBlockChainPortAddress=portAddress;
|
||||
}
|
||||
|
||||
// 将已在区块链后台注册成功的用户注销掉
|
||||
public String deleteUser(String username,String sig){
|
||||
String prefix="/"+username;
|
||||
// 获取注册数组
|
||||
byte[] registerByte=getBlockChainDeleteBuffer(prefix,sig);
|
||||
System.out.println("delete length: "+registerByte.length);
|
||||
// 通过TCP连接区块链后台
|
||||
Socket blockchainClient;
|
||||
try {
|
||||
blockchainClient=new Socket(NDNBlockChainIPAddress,NDNBlockChainPortAddress);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.out.println("连接不可达:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress);
|
||||
return e.getMessage();
|
||||
}
|
||||
System.out.println("已成功建立TCP连接:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress
|
||||
+"; 远程主机地址:"+blockchainClient.getRemoteSocketAddress());
|
||||
try {
|
||||
OutputStream outToServer = blockchainClient.getOutputStream();
|
||||
DataOutputStream out = new DataOutputStream(outToServer);
|
||||
|
||||
out.write(registerByte);
|
||||
InputStream inFromServer = blockchainClient.getInputStream();
|
||||
DataInputStream in = new DataInputStream(inFromServer);
|
||||
System.out.println("正在等待服务器响应...");
|
||||
byte[] res = new byte[4];
|
||||
in.read(res);
|
||||
int resSize = Bytes2Int_LE(res);
|
||||
System.out.println("返回值长度为:"+ resSize);
|
||||
res = new byte[resSize];
|
||||
in.read(res);
|
||||
System.out.println("返回值内容为:" + new String(res, StandardCharsets.UTF_8));
|
||||
System.out.println("服务器响应: " );
|
||||
blockchainClient.close();
|
||||
System.out.println("已关闭此次TCP连接:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress);
|
||||
// System.out.println("服务器响应: " );
|
||||
// 解析返回来的数据,如果是200,就返回true
|
||||
try {
|
||||
String resString=new String(res,StandardCharsets.UTF_8);
|
||||
System.out.println("resString: "+resString);
|
||||
JSONObject resObject=new JSONObject(resString);
|
||||
int resCode=resObject.getInt("StatusCode");
|
||||
String message=resObject.getString("Message");
|
||||
if(resCode==200){
|
||||
System.out.println("区块链销户成功:"+username);
|
||||
return "true";
|
||||
}else{
|
||||
return message;
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
return e.getMessage();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.out.println("销户时数据交换出错:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress);
|
||||
return e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
// 添加白名单
|
||||
public String addWhiteUser(String phone){
|
||||
// 获取注册数组
|
||||
@@ -117,14 +190,14 @@ public class NDNBlockChainConnectClient {
|
||||
System.out.println("返回值长度为:"+ resSize);
|
||||
res = new byte[resSize];
|
||||
in.read(res);
|
||||
System.out.println("返回值内容为:" + new String(res));
|
||||
System.out.println("返回值内容为:" + new String(res, StandardCharsets.UTF_8));
|
||||
System.out.println("服务器响应: " );
|
||||
blockchainClient.close();
|
||||
System.out.println("已关闭此次TCP连接:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress);
|
||||
// System.out.println("服务器响应: " );
|
||||
// 解析返回来的数据,如果是200,就返回true
|
||||
try {
|
||||
String resString=new String(res);
|
||||
String resString=new String(res,StandardCharsets.UTF_8);
|
||||
System.out.println("resString: "+resString);
|
||||
JSONObject resObject=new JSONObject(resString);
|
||||
int resCode=resObject.getInt("StatusCode");
|
||||
@@ -150,19 +223,15 @@ public class NDNBlockChainConnectClient {
|
||||
private byte[] getBlockChainRegisterBuffer(String username,String phone, String pubkey) {
|
||||
String registerString=getBlockChainRegisterJsonString(username,phone, pubkey);
|
||||
System.out.println("json: "+registerString);
|
||||
int jsonLen = registerString.getBytes().length;
|
||||
int jsonLen = registerString.getBytes(StandardCharsets.UTF_8).length;
|
||||
System.out.println("json len: "+jsonLen);
|
||||
byte[] registerByte=new byte[jsonLen+4];
|
||||
// System.arraycopy(intToBytesLittle(jsonLen),0,
|
||||
// registerByte,0,4);
|
||||
System.arraycopy(intToBytesLittle(jsonLen),0,
|
||||
registerByte,0,4);
|
||||
try {
|
||||
System.arraycopy(registerString.getBytes("utf-8"),
|
||||
0,registerByte,4,jsonLen);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.arraycopy(registerString.getBytes(StandardCharsets.UTF_8),
|
||||
0,registerByte,4,jsonLen);
|
||||
return registerByte;
|
||||
}
|
||||
|
||||
@@ -172,16 +241,23 @@ public class NDNBlockChainConnectClient {
|
||||
int jsonLen = registerString.getBytes().length;
|
||||
System.out.println("json len: "+jsonLen);
|
||||
byte[] registerByte=new byte[jsonLen+4];
|
||||
// System.arraycopy(intToBytesLittle(jsonLen),0,
|
||||
// registerByte,0,4);
|
||||
System.arraycopy(intToBytesLittle(jsonLen),0,
|
||||
registerByte,0,4);
|
||||
try {
|
||||
System.arraycopy(registerString.getBytes("utf-8"),
|
||||
0,registerByte,4,jsonLen);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.arraycopy(registerString.getBytes(StandardCharsets.UTF_8),
|
||||
0,registerByte,4,jsonLen);
|
||||
return registerByte;
|
||||
}
|
||||
|
||||
private byte[] getBlockChainDeleteBuffer(String prefix,String sig) {
|
||||
String registerString=getBlockChainDeleteUserJsonString(prefix,sig);
|
||||
System.out.println("json: "+registerString);
|
||||
int jsonLen = registerString.getBytes().length;
|
||||
System.out.println("json len: "+jsonLen);
|
||||
byte[] registerByte=new byte[jsonLen+4];
|
||||
System.arraycopy(intToBytesLittle(jsonLen),0,
|
||||
registerByte,0,4);
|
||||
System.arraycopy(registerString.getBytes(StandardCharsets.UTF_8),
|
||||
0,registerByte,4,jsonLen);
|
||||
return registerByte;
|
||||
}
|
||||
|
||||
@@ -231,7 +307,49 @@ public class NDNBlockChainConnectClient {
|
||||
return iRst;
|
||||
}
|
||||
|
||||
// 从前端界面获得登录数据并转换成json格式
|
||||
private String getBlockChainDeleteUserJsonString(String prefix,String sig) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
try {
|
||||
jsonObject.put("Type", "user-act");
|
||||
jsonObject.put("Command", "Destroy");
|
||||
jsonObject.put("Prefix",prefix);
|
||||
jsonObject.put("Timestamp","");
|
||||
jsonObject.put("Sig",sig);
|
||||
} catch (Exception e) {
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
}
|
||||
return jsonObject.toString();
|
||||
}
|
||||
|
||||
public static String signBuf(String prefix, CertificateV2 certificateV2){
|
||||
// 构建msg
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
try {
|
||||
jsonObject.put("Type", "user-act");
|
||||
jsonObject.put("Command", "Destroy");
|
||||
jsonObject.put("Prefix",prefix);
|
||||
jsonObject.put("Timestamp","");
|
||||
} catch (Exception e) {
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
}
|
||||
String msg=jsonObject.toString();
|
||||
ByteBuffer byteBuffer=ByteBuffer.wrap(msg.getBytes(StandardCharsets.UTF_8));// 这句是C++没有的
|
||||
try {
|
||||
SigningInfo signingInfo = new SigningInfo();
|
||||
signingInfo.setSigningIdentity(certificateV2.getIdentity());
|
||||
Blob blob= KeyManager.INSTANCE.getKeyChain().sign(byteBuffer,signingInfo);
|
||||
// String sig=blob.toHex();
|
||||
String sig=Common.base64Encode(blob.getImmutableArray(), false);
|
||||
// String sig= Common.base64Encode(signature.getSignature().getImmutableArray());
|
||||
// String sig1=signature.getSignature().toHex();
|
||||
System.out.println("sig: "+sig);
|
||||
return sig;
|
||||
} catch (PibImpl.Error | KeyChain.Error | TpmBackEnd.Error e) {
|
||||
e.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String getBlockChainWhiteUserJsonString(String phone) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
String typeString = "whiteUser";
|
||||
|
||||
@@ -7,6 +7,7 @@ import cn.minoa.dataRequestInterface.OrderInfo;
|
||||
import cn.minoa.dataRequestInterface.ResponseData;
|
||||
import cn.minoa.util.EncryptionUtil;
|
||||
import cn.minoa.util.KeyStorageUtil;
|
||||
import cn.minoa.util.RegisterUtil;
|
||||
import cn.minoa.util.StringByteLengthUtil;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Alert;
|
||||
@@ -15,7 +16,12 @@ import javafx.scene.control.TextField;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.stage.Stage;
|
||||
import net.named_data.jndn.Interest;
|
||||
import net.named_data.jndn.Name;
|
||||
import net.named_data.jndn.Signature;
|
||||
import net.named_data.jndn.security.KeyChain;
|
||||
import net.named_data.jndn.security.SecurityException;
|
||||
import net.named_data.jndn.security.SigningInfo;
|
||||
import net.named_data.jndn.security.pib.Pib;
|
||||
import net.named_data.jndn.security.pib.PibImpl;
|
||||
import net.named_data.jndn.security.tpm.Tpm;
|
||||
@@ -26,6 +32,8 @@ import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class RegisterOverviewController {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@@ -72,7 +80,7 @@ public class RegisterOverviewController {
|
||||
Long seqLong = mainApp.getNewDataReqId();
|
||||
orderInfo.setSeq(seqLong);
|
||||
// 生成本地pid.db文件,获取公钥
|
||||
String publicKey="";
|
||||
String publicKey ;
|
||||
try {
|
||||
CertificateV2 certificateV2= KeyManager.INSTANCE.initKeyChain(keyChainNameString).getCertification(keyChainNameString);
|
||||
publicKey = Common.base64Encode(certificateV2.wireEncode().getImmutableArray(), false);
|
||||
@@ -85,28 +93,41 @@ public class RegisterOverviewController {
|
||||
Alert alert = new Alert(Alert.AlertType.INFORMATION);
|
||||
alert.setTitle("注册失败");
|
||||
alert.setHeaderText("注册账号失败");
|
||||
alert.setContentText("本地密钥生成失败:\n"+error.getMessage());
|
||||
alert.setContentText("本地密钥生成失败:\n"+error.getMessage()+"\n"
|
||||
+"建议更换用户名,重新进行注册!");
|
||||
alert.showAndWait();
|
||||
return ;
|
||||
}
|
||||
// 首先向区块链发送注册信息
|
||||
String pubkey=publicKey;
|
||||
// String pubkey = "Bv0CIgcvCAVsbGFhYQgDS0VZCAhyVwiW+kaX7QgMY2VydC1yZXF1ZXN0CAn9AAABcSP8KDIUCRgBAhkEAiVRABX9AU8wggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAEgCbgPaAk0RRziBAW/beuF5fBQdJdbZhtKrT+FRdXq6sqPxvhM3VQF+WrBehiA5TsKpLzwzNoE8kKt8gyevM4dxZHGwEDHBgHFggFbGxhYWEIA0tFWQgIclcIlvpGl+39AP0m/QD+DzIwMjAwMzI5VDAxNTEwMf0A/w8yMDIwMDQwOFQwMTUxMDAXSDBGAiEApxH8lJntSBM/NwV+laSdifH674+76xZnxVF4vKGaXXkCIQCj3OyzagvjqYrJmZ9f00PWVISXRyrIrKmwFbwzsk/hQw==";
|
||||
String phonenumber=phoneNumber.getText().trim();
|
||||
NDNBlockChainConnectClient ndnBlockChainConnectClient=new NDNBlockChainConnectClient();
|
||||
String resString=ndnBlockChainConnectClient.registeNewUser(username,
|
||||
phonenumber,pubkey);
|
||||
if(resString.equals("true")){
|
||||
System.out.println("用户【"+username+"】在区块链后台被成功注册");
|
||||
}else{
|
||||
System.out.println("区块链后台注册用户【"+username+"】失败: "+resString);
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||
alert.setTitle("区块链注册失败");
|
||||
alert.setHeaderText("区块链注册失败");
|
||||
alert.setContentText("失败原因:\n"+resString);
|
||||
alert.showAndWait();
|
||||
return ;
|
||||
// 标志该用户是否已经通过了区块链注册
|
||||
boolean b_flag=RegisterUtil.isAccessedBlockUser(keyChainNameString);
|
||||
// 如果没有注册成功过,向区块链发送注册信息;否则,跳过区块链注册
|
||||
if(!b_flag) {
|
||||
String pubkey = publicKey;
|
||||
String phonenumber = phoneNumber.getText().trim();
|
||||
NDNBlockChainConnectClient ndnBlockChainConnectClient = new NDNBlockChainConnectClient();
|
||||
String resString = ndnBlockChainConnectClient.registeNewUser(username,
|
||||
phonenumber, pubkey);
|
||||
if (resString.equals("true")) {
|
||||
System.out.println("用户【" + username + "】在区块链后台被成功注册");
|
||||
} else {
|
||||
// 区块链没有注册用户成功,则删掉刚刚生成的密钥文件
|
||||
try {
|
||||
KeyManager.INSTANCE.getKeyChain().deleteIdentity(new Name(keyChainNameString));
|
||||
System.out.println("已删除本地密钥:"+keyChainNameString);
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("区块链后台注册用户【" + username + "】失败: " + resString);
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||
alert.setTitle("区块链注册失败");
|
||||
alert.setHeaderText("区块链注册失败");
|
||||
alert.setContentText("失败原因:\n" + resString+"\n"
|
||||
+"请确保你输入的手机号在系统白名单中,且用户名并没有被注册过。\n " +
|
||||
"您可以将用户名适当复杂化,以保证其在系统中的唯一性。");
|
||||
alert.showAndWait();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 获取注册时JSON
|
||||
String registerJson=getRegisterJson(publicKey);
|
||||
@@ -127,7 +148,11 @@ public class RegisterOverviewController {
|
||||
}
|
||||
if (codeInteger == 200) {
|
||||
// 注册之后,使用getNews消耗掉新通知
|
||||
makeNoticesBeRead();
|
||||
// makeNoticesBeRead();
|
||||
// 如果该用户是原来注册中断的用户,移除其本地信息
|
||||
if(b_flag) {
|
||||
RegisterUtil.deleteAccessedBlockUser(keyChainNameString);
|
||||
}
|
||||
// 将此时的keyChainName持久化到本地
|
||||
MinoaDataAPI.keyChainNameString=keyChainNameString;
|
||||
KeyStorageUtil.setKeyName(keyChainNameString);
|
||||
@@ -139,11 +164,20 @@ public class RegisterOverviewController {
|
||||
alert.showAndWait();
|
||||
dialogStage.close();
|
||||
} else {
|
||||
// 后台没有注册用户成功,则删掉刚刚生成的密钥文件
|
||||
try {
|
||||
KeyManager.INSTANCE.getKeyChain().deleteIdentity(new Name(keyChainNameString));
|
||||
System.out.println("已删除本地密钥:"+keyChainNameString);
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 将该用户(区块链注册成功,后台注册失败)的注册前缀,保存到本地
|
||||
RegisterUtil.setAccessedBlockUser(keyChainNameString);
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(Alert.AlertType.WARNING);
|
||||
alert.setTitle("注册失败");
|
||||
alert.setHeaderText("注册失败");
|
||||
alert.setContentText("请确保你输入的手机号在系统白名单中,且登录名/账户/昵称并没有被注册过。\n " +
|
||||
alert.setContentText("请确保你输入的手机号在系统白名单中,且用户名并没有被注册过。\n " +
|
||||
"您可以将用户名适当复杂化,以保证其在系统中的唯一性。");
|
||||
alert.showAndWait();
|
||||
}
|
||||
@@ -321,12 +355,13 @@ public class RegisterOverviewController {
|
||||
// 验证输入内容格式
|
||||
private boolean isRightContent() {
|
||||
//验证昵称是否为空
|
||||
if (nickname.getText().trim().equals("")||nickname.getText().trim().contains("@")) {
|
||||
if (nickname.getText().trim().equals("")||nickname.getText().trim().contains("@")||nickname.getText().trim().contains(" ")) {
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(Alert.AlertType.WARNING);
|
||||
alert.setTitle("账号错误");
|
||||
alert.setHeaderText("你的账号错误");
|
||||
alert.setContentText("请确保你输入的账号(昵称)不为空,且昵称中不包含\"@\"字符");
|
||||
alert.setContentText("请确保你输入的账号(昵称)不为空,且昵称中不包含\"@\"字符;\n" +
|
||||
"此外,请确保输入的昵称中不包含空格");
|
||||
alert.showAndWait();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import java.io.*;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
//import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -28,6 +29,12 @@ public class SettingOverviewController {
|
||||
@FXML
|
||||
private TextField packetPrefix;
|
||||
@FXML
|
||||
private TextField fileThread;
|
||||
@FXML
|
||||
private TextField BlockIP;
|
||||
@FXML
|
||||
private TextField BlockPort;
|
||||
@FXML
|
||||
private ImageView miniLogo;
|
||||
|
||||
public SettingOverviewController(){
|
||||
@@ -40,6 +47,9 @@ public class SettingOverviewController {
|
||||
ipAddress.setPromptText("IP格式示例:121.15.171.89");
|
||||
portAddress.setPromptText("端口号格式示例:6363");
|
||||
packetPrefix.setPromptText("格式示例:/ndn/edu/pkusz/OA)");
|
||||
fileThread.setPromptText("文件传输并发数[1-100]");
|
||||
BlockIP.setPromptText("IP格式示例:121.15.171.89");
|
||||
BlockPort.setPromptText("端口号格式示例:8010");
|
||||
}
|
||||
|
||||
// 根据表单修改配置文件
|
||||
@@ -49,12 +59,13 @@ public class SettingOverviewController {
|
||||
//修改本地配置文件
|
||||
changeSettingProperties();
|
||||
mainApp.loadSettingProperties();
|
||||
reloadSetting();
|
||||
//弹窗提示
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(Alert.AlertType.INFORMATION);
|
||||
alert.setTitle("设置成功");
|
||||
alert.setHeaderText("服务器地址/包前缀修改成功");
|
||||
alert.setContentText("您已成功修改服务器IP/包前缀。\n请重新启动应用以生效新设置!");
|
||||
alert.setHeaderText("配置文件修改成功");
|
||||
alert.setContentText("您已成功修改系统配置。\n请重新启动应用以生效新设置!");
|
||||
alert.showAndWait();
|
||||
System.exit(0);
|
||||
}
|
||||
@@ -70,16 +81,23 @@ public class SettingOverviewController {
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到配置文件...");
|
||||
}
|
||||
// 解决中文乱码问题
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(inputStream);
|
||||
settingProperties.load(bf);
|
||||
settingProperties.setProperty("ServerIPAddress",ipAddress.getText().trim());
|
||||
settingProperties.setProperty("ServerPortAddress",portAddress.getText().trim());
|
||||
settingProperties.setProperty("DataPackagePrefix",packetPrefix.getText().trim());
|
||||
settingProperties.setProperty("ThreadNumberForFileTransfer",fileThread.getText().trim());
|
||||
settingProperties.setProperty("ndnBlockChainIPAddress",BlockIP.getText().trim());
|
||||
settingProperties.setProperty("ndnBlockChainPortAddress",BlockPort.getText().trim());
|
||||
|
||||
outputStream=new BufferedOutputStream(new FileOutputStream(mainApp.getClientPath()+ File.separator+"ndn"+File.separator+"settings.properties"));
|
||||
// 解决中文乱码问题
|
||||
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
|
||||
// URL url = MainApp.class.getClassLoader().getResource("ndn/settings.properties");
|
||||
// outputStream = new FileOutputStream(url.getPath());
|
||||
settingProperties.store(outputStream,"修改配置文件");
|
||||
settingProperties.store(bw,"修改配置文件");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}finally{
|
||||
@@ -102,6 +120,15 @@ public class SettingOverviewController {
|
||||
}
|
||||
}
|
||||
|
||||
// 重载参数
|
||||
private void reloadSetting(){
|
||||
ipAddress.setText(mainApp.minoaServerIpString);
|
||||
portAddress.setText(mainApp.minoaServerPortInteger.toString());
|
||||
fileThread.setText(mainApp.threadNumberForFileTransfer.toString());
|
||||
packetPrefix.setText(mainApp.globalPrefixString);
|
||||
packetPrefix.setDisable(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* @param mainApp
|
||||
*/
|
||||
@@ -109,8 +136,11 @@ public class SettingOverviewController {
|
||||
this.mainApp = mainApp;
|
||||
ipAddress.setText(mainApp.minoaServerIpString);
|
||||
portAddress.setText(mainApp.minoaServerPortInteger.toString());
|
||||
fileThread.setText(mainApp.threadNumberForFileTransfer.toString());
|
||||
packetPrefix.setText(mainApp.globalPrefixString);
|
||||
packetPrefix.setDisable(true);
|
||||
BlockIP.setText(mainApp.NDNBlockChainIPAddress);
|
||||
BlockPort.setText(mainApp.NDNBlockChainPortAddress.toString());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -192,6 +222,36 @@ public class SettingOverviewController {
|
||||
alert.showAndWait();
|
||||
return false;
|
||||
}
|
||||
//验证前缀是否为空
|
||||
if (fileThread.getText().trim().equals("")) {
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(Alert.AlertType.WARNING);
|
||||
alert.setTitle("线程数错误");
|
||||
alert.setHeaderText("你的线程数错误");
|
||||
alert.setContentText("请确保你输入的线程数不为空。");
|
||||
alert.showAndWait();
|
||||
return false;
|
||||
}
|
||||
//判断线程数是否正确
|
||||
boolean flag_thread=true;
|
||||
try{
|
||||
Integer threadnumber=Integer.parseInt(fileThread.getText().trim());
|
||||
if((threadnumber<1)||(threadnumber>100)){
|
||||
flag_thread=false;
|
||||
}
|
||||
}catch(Exception e){
|
||||
flag_thread=false;
|
||||
}finally {
|
||||
if(flag_thread==false){
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(Alert.AlertType.WARNING);
|
||||
alert.setTitle("线程数错误");
|
||||
alert.setHeaderText("你的线程数错误");
|
||||
alert.setContentText("请确保你输入的文件传输线程数是正整数且范围在1-100之间。");
|
||||
alert.showAndWait();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//使用socket判断这里的ip和端口号是否可以连接上
|
||||
String ipHost=ipAddress.getText().trim();
|
||||
Integer portHost=Integer.parseInt(portAddress.getText().trim());
|
||||
@@ -204,6 +264,68 @@ public class SettingOverviewController {
|
||||
alert.showAndWait();
|
||||
return false;
|
||||
}
|
||||
//验证IP是否为空
|
||||
if (BlockIP.getText().trim().equals("")) {
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(Alert.AlertType.WARNING);
|
||||
alert.setTitle("IP错误");
|
||||
alert.setHeaderText("你的区块链IP错误");
|
||||
alert.setContentText("请确保你输入的区块链IP不为空。");
|
||||
alert.showAndWait();
|
||||
return false;
|
||||
}
|
||||
//验证IP格式是否正确
|
||||
if (!ipCheck(BlockIP.getText().trim())) {
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(Alert.AlertType.WARNING);
|
||||
alert.setTitle("IP错误");
|
||||
alert.setHeaderText("你的区块链IP错误");
|
||||
alert.setContentText("请确保你输入的区块链IP格式正确。");
|
||||
alert.showAndWait();
|
||||
return false;
|
||||
}
|
||||
//验证端口号是否为空
|
||||
if (BlockPort.getText().trim().equals("")) {
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(Alert.AlertType.WARNING);
|
||||
alert.setTitle("端口号错误");
|
||||
alert.setHeaderText("你的区块链端口号错误");
|
||||
alert.setContentText("请确保你输入的区块链端口号不为空。");
|
||||
alert.showAndWait();
|
||||
return false;
|
||||
}
|
||||
//判断端口号是否正确
|
||||
boolean flag_b_port=true;
|
||||
try{
|
||||
Integer port=Integer.parseInt(BlockPort.getText().trim());
|
||||
if((port<1)||(port>65535)){
|
||||
flag_b_port=false;
|
||||
}
|
||||
}catch(Exception e){
|
||||
flag_b_port=false;
|
||||
}finally {
|
||||
if(flag_b_port==false){
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(Alert.AlertType.WARNING);
|
||||
alert.setTitle("端口号错误");
|
||||
alert.setHeaderText("你的区块链端口号错误");
|
||||
alert.setContentText("请确保你输入的区块链端口号格式正确。");
|
||||
alert.showAndWait();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//使用socket判断这里的ip和端口号是否可以连接上
|
||||
ipHost=BlockIP.getText().trim();
|
||||
portHost=Integer.parseInt(BlockPort.getText().trim());
|
||||
if(!isHostConnectable(ipHost,portHost)){
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(Alert.AlertType.WARNING);
|
||||
alert.setTitle("连接错误");
|
||||
alert.setHeaderText("地址连接错误");
|
||||
alert.setContentText("请确保你输入的区块链IP及端口号是可达的。");
|
||||
alert.showAndWait();
|
||||
return false;
|
||||
}
|
||||
//判断是否与原内容一致
|
||||
if(isNotChange()){
|
||||
Alert alert = new Alert(Alert.AlertType.WARNING);
|
||||
@@ -219,8 +341,11 @@ public class SettingOverviewController {
|
||||
// 判断新设置的参数是否与原参数一致
|
||||
public boolean isNotChange(){
|
||||
if(ipAddress.getText().trim().equals(mainApp.minoaServerIpString)&&
|
||||
portAddress.getText().trim().equals(mainApp.minoaServerPortInteger.toString())&&
|
||||
packetPrefix.getText().trim().equals(mainApp.globalPrefixString)){
|
||||
portAddress.getText().trim().equals(mainApp.minoaServerPortInteger.toString())&&
|
||||
packetPrefix.getText().trim().equals(mainApp.globalPrefixString)&&
|
||||
fileThread.getText().trim().equals(mainApp.threadNumberForFileTransfer.toString())&&
|
||||
BlockIP.getText().trim().equals(mainApp.NDNBlockChainIPAddress)&&
|
||||
BlockPort.getText().trim().equals(mainApp.NDNBlockChainPortAddress.toString())){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
|
||||
@@ -3,7 +3,7 @@ package cn.minoa.view.mine;
|
||||
import java.io.File;
|
||||
|
||||
import cn.minoa.MainApp;
|
||||
import cn.minoa.dataRequestInterface.DownLoadClientBasedFacePool;
|
||||
import cn.minoa.dataRequestInterface.DownLoadClientBPRenewal;
|
||||
import cn.minoa.model.Email;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Alert;
|
||||
@@ -14,7 +14,6 @@ import javafx.scene.control.Alert.AlertType;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
public class SingleEmailDetailsController {
|
||||
@@ -132,7 +131,7 @@ public class SingleEmailDetailsController {
|
||||
sliceNum++;
|
||||
}
|
||||
Long startTime = System.currentTimeMillis();
|
||||
DownLoadClientBasedFacePool downLoadClient = new DownLoadClientBasedFacePool(pathfilename,
|
||||
DownLoadClientBPRenewal downLoadClient = new DownLoadClientBPRenewal(pathfilename,
|
||||
localDirString,sliceNum,mainApp.threadNumberForFileTransfer);
|
||||
// 下载文件
|
||||
boolean res = downLoadClient.downloadData();
|
||||
|
||||
@@ -8,37 +8,46 @@
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
|
||||
<AnchorPane prefHeight="325.0" prefWidth="425.0" stylesheets="@Register.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cn.minoa.view.login.SettingOverviewController">
|
||||
<children>
|
||||
<Button mnemonicParsing="false" opacity="0.0" text="避免聚焦" />
|
||||
<AnchorPane fx:id="upSplite" opacity="0.45" prefHeight="80.0" prefWidth="200.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<ImageView fx:id="miniLogo" fitHeight="35.0" fitWidth="35.0" layoutX="-50.0" layoutY="-47.0" pickOnBounds="true" preserveRatio="true" AnchorPane.leftAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
<Label layoutX="37.0" layoutY="12.0" prefHeight="35.0" text="minoa" AnchorPane.leftAnchor="40.0" AnchorPane.topAnchor="2.0">
|
||||
<font>
|
||||
<Font name="Arial Black" size="12.0" />
|
||||
</font></Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<GridPane layoutX="152.0" layoutY="110.0" AnchorPane.bottomAnchor="100.0" AnchorPane.leftAnchor="100.0" AnchorPane.rightAnchor="100.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="108.0" minWidth="10.0" prefWidth="57.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="172.0" minWidth="10.0" prefWidth="168.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<TextField fx:id="ipAddress" GridPane.columnIndex="1" />
|
||||
<Label text="IP地址" />
|
||||
<Label text="端口号" GridPane.rowIndex="1" />
|
||||
<Label text="包前缀" GridPane.rowIndex="2" />
|
||||
<TextField fx:id="packetPrefix" GridPane.columnIndex="1" GridPane.rowIndex="2" />
|
||||
<TextField fx:id="portAddress" GridPane.columnIndex="1" GridPane.rowIndex="1" />
|
||||
</children>
|
||||
</GridPane>
|
||||
<Button layoutX="112.0" layoutY="263.0" mnemonicParsing="false" onAction="#handleSetting" prefHeight="35.0" prefWidth="225.0" text="确定" AnchorPane.bottomAnchor="27.0" AnchorPane.leftAnchor="100.0" AnchorPane.rightAnchor="100.0" />
|
||||
</children>
|
||||
<children>
|
||||
<Button mnemonicParsing="false" opacity="0.0" text="避免聚焦" />
|
||||
<AnchorPane fx:id="upSplite" opacity="0.45" prefHeight="80.0" prefWidth="200.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<ImageView fx:id="miniLogo" fitHeight="35.0" fitWidth="35.0" layoutX="-50.0" layoutY="-47.0" pickOnBounds="true" preserveRatio="true" AnchorPane.leftAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
<Label layoutX="37.0" layoutY="12.0" prefHeight="35.0" text="文件管理系统" AnchorPane.leftAnchor="40.0" AnchorPane.topAnchor="2.0">
|
||||
<font>
|
||||
<Font name="Arial Black" size="12.0" />
|
||||
</font></Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<GridPane layoutX="152.0" layoutY="110.0" AnchorPane.bottomAnchor="65.0" AnchorPane.leftAnchor="80.0" AnchorPane.rightAnchor="80.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="108.0" minWidth="10.0" prefWidth="85.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="182.0" minWidth="10.0" prefWidth="140.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<TextField fx:id="ipAddress" GridPane.columnIndex="1" />
|
||||
<Label text="后台IP地址" />
|
||||
<Label text="后台端口号" GridPane.rowIndex="1" />
|
||||
<Label text="服务前缀" GridPane.rowIndex="2" />
|
||||
<TextField fx:id="packetPrefix" GridPane.columnIndex="1" GridPane.rowIndex="2" />
|
||||
<TextField fx:id="portAddress" GridPane.columnIndex="1" GridPane.rowIndex="1" />
|
||||
<Label text="文件传输并发数" GridPane.rowIndex="3" />
|
||||
<TextField fx:id="fileThread" GridPane.columnIndex="1" GridPane.rowIndex="3" />
|
||||
<Label text="区块链IP地址" GridPane.rowIndex="4" />
|
||||
<Label text="区块链端口号" GridPane.rowIndex="5" />
|
||||
<TextField fx:id="BlockIP" GridPane.columnIndex="1" GridPane.rowIndex="4" />
|
||||
<TextField fx:id="BlockPort" GridPane.columnIndex="1" GridPane.rowIndex="5" />
|
||||
</children>
|
||||
</GridPane>
|
||||
<Button layoutX="112.0" layoutY="263.0" mnemonicParsing="false" onAction="#handleSetting" prefHeight="35.0" prefWidth="225.0" text="确定" AnchorPane.bottomAnchor="27.0" AnchorPane.leftAnchor="100.0" AnchorPane.rightAnchor="100.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
Reference in new issue
Block a user