first commit

master
王宇洋 3 years ago
parent 775443f68a
commit 217e3f7506

23
.gitignore vendored

@ -0,0 +1,23 @@
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

8
.idea/.gitignore vendored

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

@ -0,0 +1,20 @@
<component name="ArtifactManager">
<artifact type="jar" name="Client">
<output-path>$PROJECT_DIR$/out/artifacts/Client</output-path>
<root id="archive" name="P2P_Project.jar">
<element id="directory" name="META-INF">
<element id="file-copy" path="$PROJECT_DIR$/Client-META-INF/META-INF/MANIFEST.MF" />
</element>
<element id="module-output" name="P2P_Project" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-fxml/11.0.2/javafx-fxml-11.0.2-mac.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-base/11.0.2/javafx-base-11.0.2.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-controls/11.0.2/javafx-controls-11.0.2-mac.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-graphics/11.0.2/javafx-graphics-11.0.2-mac.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-base/11.0.2/javafx-base-11.0.2-mac.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-controls/11.0.2/javafx-controls-11.0.2.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-fxml/11.0.2/javafx-fxml-11.0.2.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-graphics/11.0.2/javafx-graphics-11.0.2.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/cn/hutool/hutool-all/5.7.13/hutool-all-5.7.13.jar" path-in-jar="/" />
</root>
</artifact>
</component>

@ -0,0 +1,20 @@
<component name="ArtifactManager">
<artifact type="jar" name="Server">
<output-path>$PROJECT_DIR$/out/artifacts/Server</output-path>
<root id="archive" name="P2P_Project.jar">
<element id="directory" name="META-INF">
<element id="file-copy" path="$PROJECT_DIR$/Server-META-INF/META-INF/MANIFEST.MF" />
</element>
<element id="module-output" name="P2P_Project" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-fxml/11.0.2/javafx-fxml-11.0.2-mac.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-base/11.0.2/javafx-base-11.0.2.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-controls/11.0.2/javafx-controls-11.0.2-mac.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-graphics/11.0.2/javafx-graphics-11.0.2-mac.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-base/11.0.2/javafx-base-11.0.2-mac.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-controls/11.0.2/javafx-controls-11.0.2.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-fxml/11.0.2/javafx-fxml-11.0.2.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-graphics/11.0.2/javafx-graphics-11.0.2.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/cn/hutool/hutool-all/5.7.13/hutool-all-5.7.13.jar" path-in-jar="/" />
</root>
</artifact>
</component>

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile default="true" name="Default" enabled="true" />
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="P2P_Project" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel>
<module name="P2P_Project" target="8" />
</bytecodeTargetLevel>
</component>
</project>

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="http://maven.aliyun.com/nexus/content/groups/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: cn.hutool:hutool-all:5.7.13">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/cn/hutool/hutool-all/5.7.13/hutool-all-5.7.13.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/cn/hutool/hutool-all/5.7.13/hutool-all-5.7.13-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/cn/hutool/hutool-all/5.7.13/hutool-all-5.7.13-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.openjfx:javafx-base:11.0.2">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-base/11.0.2/javafx-base-11.0.2.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-base/11.0.2/javafx-base-11.0.2-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-base/11.0.2/javafx-base-11.0.2-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.openjfx:javafx-base:mac:11.0.2">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-base/11.0.2/javafx-base-11.0.2-mac.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-base/11.0.2/javafx-base-11.0.2-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-base/11.0.2/javafx-base-11.0.2-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.openjfx:javafx-controls:11.0.2">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-controls/11.0.2/javafx-controls-11.0.2.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-controls/11.0.2/javafx-controls-11.0.2-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-controls/11.0.2/javafx-controls-11.0.2-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.openjfx:javafx-controls:mac:11.0.2">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-controls/11.0.2/javafx-controls-11.0.2-mac.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-controls/11.0.2/javafx-controls-11.0.2-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-controls/11.0.2/javafx-controls-11.0.2-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.openjfx:javafx-fxml:11.0.2">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-fxml/11.0.2/javafx-fxml-11.0.2.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-fxml/11.0.2/javafx-fxml-11.0.2-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-fxml/11.0.2/javafx-fxml-11.0.2-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.openjfx:javafx-fxml:mac:11.0.2">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-fxml/11.0.2/javafx-fxml-11.0.2-mac.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-fxml/11.0.2/javafx-fxml-11.0.2-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-fxml/11.0.2/javafx-fxml-11.0.2-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.openjfx:javafx-graphics:11.0.2">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-graphics/11.0.2/javafx-graphics-11.0.2.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-graphics/11.0.2/javafx-graphics-11.0.2-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-graphics/11.0.2/javafx-graphics-11.0.2-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.openjfx:javafx-graphics:mac:11.0.2">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-graphics/11.0.2/javafx-graphics-11.0.2-mac.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-graphics/11.0.2/javafx-graphics-11.0.2-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/openjfx/javafx-graphics/11.0.2/javafx-graphics-11.0.2-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="JavaSE-1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/P2P_Project.iml" filepath="$PROJECT_DIR$/P2P_Project.iml" />
</modules>
</component>
</project>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
</set>
</option>
</component>
</project>

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: com.echo.p2p_project.client.ClientMain

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.openjfx:javafx-controls:11.0.2" level="project" />
<orderEntry type="library" name="Maven: org.openjfx:javafx-controls:mac:11.0.2" level="project" />
<orderEntry type="library" name="Maven: org.openjfx:javafx-graphics:11.0.2" level="project" />
<orderEntry type="library" name="Maven: org.openjfx:javafx-graphics:mac:11.0.2" level="project" />
<orderEntry type="library" name="Maven: org.openjfx:javafx-base:11.0.2" level="project" />
<orderEntry type="library" name="Maven: org.openjfx:javafx-base:mac:11.0.2" level="project" />
<orderEntry type="library" name="Maven: org.openjfx:javafx-fxml:11.0.2" level="project" />
<orderEntry type="library" name="Maven: org.openjfx:javafx-fxml:mac:11.0.2" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.7.13" level="project" />
</component>
</module>

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: com.echo.p2p_project.server.ServerMain

@ -0,0 +1,5 @@
hahaha
================
This File is 1.a
================

@ -0,0 +1,5 @@
2222222222222222
================
This File is 2.a
================

@ -0,0 +1,5 @@
hahaha
================
This File is 1.a
================

@ -0,0 +1,437 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.COMP3013J</groupId>
<artifactId>COMP3013J</artifactId>
<version>1.0-SNAPSHOT</version>
<name>COMP3013J</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<!-- &lt;!&ndash;使用阿里云包源,提高下载速度&ndash;&gt;-->
<!-- <repositories>-->
<!-- <repository>-->
<!-- &lt;!&ndash;创建私服的地址&ndash;&gt;-->
<!-- <id>aliyun</id>-->
<!-- <name>aliyun</name>-->
<!-- <url>https://maven.aliyun.com/repository/public</url>-->
<!-- </repository>-->
<!-- </repositories>-->
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11.0.2</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>11.0.2</version>
</dependency>
<!-- &lt;!&ndash;引入mybatis框架&ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>org.mybatis</groupId>-->
<!-- <artifactId>mybatis</artifactId>-->
<!-- <version>3.5.1</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.xerial</groupId>-->
<!-- <artifactId>sqlite-jdbc</artifactId>-->
<!-- <version>3.36.0.3</version>-->
<!-- </dependency>-->
<!-- &lt;!&ndash;单元测试组件&ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>junit</groupId>-->
<!-- <artifactId>junit</artifactId>-->
<!-- <version>4.13.2</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.baidu.aip</groupId>-->
<!-- <artifactId>java-sdk</artifactId>-->
<!-- <version>4.16.2</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>javazoom</groupId>-->
<!-- <artifactId>jlayer</artifactId>-->
<!-- <version>1.0.1</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>junit</groupId>-->
<!-- <artifactId>junit</artifactId>-->
<!-- <version>4.13.2</version>-->
<!-- <scope>test</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.alibaba</groupId>-->
<!-- <artifactId>fastjson</artifactId>-->
<!-- <version>1.2.78</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.aliyun</groupId>-->
<!-- <artifactId>aliyun-java-sdk-ecs</artifactId>-->
<!-- <version>4.24.8</version>-->
<!-- </dependency>-->
<!-- &lt;!&ndash; https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>com.squareup.okhttp3</groupId>-->
<!-- <artifactId>okhttp</artifactId>-->
<!-- <version>4.9.1</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.google.code.gson</groupId>-->
<!-- <artifactId>gson</artifactId>-->
<!-- <version>2.8.8</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.aliyun</groupId>-->
<!-- <artifactId>aliyun-java-sdk-cr</artifactId>-->
<!-- <version>4.1.2</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.aliyun</groupId>-->
<!-- <artifactId>aliyun-java-sdk-core</artifactId>-->
<!-- <version>4.5.25</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.aliyun</groupId>-->
<!-- <artifactId>aliyun-java-sdk-alimt</artifactId>-->
<!-- <version>3.0.30</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-compiler-plugin</artifactId>-->
<!-- <version>3.8.1</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.slf4j</groupId>-->
<!-- <artifactId>slf4j-simple</artifactId>-->
<!-- <version>1.7.32</version>-->
<!-- </dependency>-->
<!-- &lt;!&ndash; https://mvnrepository.com/artifact/com.squareup.okio/okio &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>com.squareup.okio</groupId>-->
<!-- <artifactId>okio</artifactId>-->
<!-- <version>2.10.0</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-assembly-plugin</artifactId>-->
<!-- <version>3.3.0</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.apache.joshua</groupId>-->
<!-- <artifactId>joshua-incubating</artifactId>-->
<!-- <version>6.1</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>io.github.vincenzopalazzo</groupId>-->
<!-- <artifactId>material-ui-swing</artifactId>-->
<!-- <version>1.1.2</version>-->
<!-- </dependency>-->
<!--&lt;!&ndash; <dependency>&ndash;&gt;-->
<!--&lt;!&ndash; <groupId>com.tencentcloudapi</groupId>&ndash;&gt;-->
<!--&lt;!&ndash; <artifactId>tencentcloud-sdk-java</artifactId>&ndash;&gt;-->
<!--&lt;!&ndash; &lt;!&ndash; go to https://search.maven.org/search?q=tencentcloud-sdk-java and get the latest version. &ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash; &lt;!&ndash; 请到https://search.maven.org/search?q=tencentcloud-sdk-java查询所有版本最新版本如下 &ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash; <version>4.0.11</version>&ndash;&gt;-->
<!--&lt;!&ndash; </dependency>&ndash;&gt;-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.13</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.akathist.maven.plugins.launch4j</groupId>-->
<!-- <artifactId>launch4j-maven-plugin</artifactId>-->
<!-- <version>2.1.2</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.sshtools</groupId>-->
<!-- <artifactId>icon-generator-swing</artifactId>-->
<!-- <version>1.4.3</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.google.zxing</groupId>-->
<!-- <artifactId>core</artifactId>-->
<!-- <version>3.4.1</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.jacoco</groupId>-->
<!-- <artifactId>jacoco-maven-plugin</artifactId>-->
<!-- <version>0.8.7</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.baidu.aip</groupId>-->
<!-- <artifactId>java-sdk</artifactId>-->
<!-- <version>4.16.2</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.alibaba.nls</groupId>-->
<!-- <artifactId>nls-sdk-transcriber</artifactId>-->
<!-- <version>2.2.1</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.github.weisj</groupId>-->
<!-- <artifactId>darklaf-core</artifactId>-->
<!-- <version>2.7.3</version>-->
<!-- </dependency>-->
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<mainClass>com.util.old.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<!-- get all project dependencies -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<!-- MainClass in mainfest make a executable jar -->
<archive>
<manifest>
<mainClass>com.util.old.Main</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- bind to the packaging phase -->
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>.settings/**</exclude>
<exclude>*.classpath</exclude>
<exclude>*.project</exclude>
<exclude>*.txt</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
<!-- <plugin>-->
<!-- <groupId>com.akathist.maven.plugins.launch4j</groupId>-->
<!-- <artifactId>launch4j-maven-plugin</artifactId>-->
<!-- <version>2.0.1</version>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <id>l4j-gui</id>-->
<!-- <phase>package</phase>-->
<!-- <goals>-->
<!-- <goal>launch4j</goal>-->
<!-- </goals>-->
<!-- <configuration>-->
<!-- <headerType>gui</headerType>-->
<!-- <outfile>target/YOTO_Translator.exe</outfile>-->
<!-- <jar>target/${project.artifactId}-${project.version}.jar</jar>-->
<!-- &lt;!&ndash; if <dontWrapJar>true</dontWrapJar> change to this conf <jar>${project.artifactId}-${project.version}.jar</jar> &ndash;&gt;-->
<!-- <dontWrapJar>false</dontWrapJar>-->
<!-- <errTitle>Error in launch4j plugin</errTitle>-->
<!-- <classPath>-->
<!-- <mainClass>com.Group_Six.Window</mainClass>-->
<!-- </classPath>-->
<!-- <icon>AppIcon.ico</icon>-->
<!-- <jre>-->
<!-- <minVersion>1.5.0</minVersion>-->
<!-- <maxVersion>15.0</maxVersion>-->
<!-- <initialHeapSize>512</initialHeapSize>-->
<!-- <maxHeapSize>1024</maxHeapSize>-->
<!-- </jre>-->
<!-- <versionInfo>-->
<!-- <fileVersion>1.0.0.0</fileVersion>-->
<!-- <txtFileVersion>1.0.0.0</txtFileVersion>-->
<!-- <fileDescription>YOTO_Translator</fileDescription>-->
<!-- <copyright>COMP2008J_Group_Six Copyright (c) 2021 </copyright>-->
<!-- <companyName>COMP2008J_Group_Six</companyName>-->
<!-- <productVersion>3.0.0.0</productVersion>-->
<!-- <txtProductVersion>${project.version}</txtProductVersion>-->
<!-- <productName>YOTO_Translator</productName>-->
<!-- <internalName>YOTO_Translator</internalName>-->
<!-- <originalFilename>YOTO_Translator.exe</originalFilename>-->
<!-- </versionInfo>-->
<!-- </configuration>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.3</version>
<configuration>
<excludes>
<!-- <exclude>com/Group_Six/View/**/*</exclude>-->
</excludes>
<includes>
<include>com/**/*</include>
<!-- <include>com/Group_Six/Database/**/*</include>-->
<!-- <include>com/Group_Six/Utils/**/*</include>-->
</includes>
</configuration>
<executions>
<execution>
<id>pre-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>post-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,5 @@
0000000000000000
================
This File is 0.a
================

@ -0,0 +1,5 @@
hahaha
================
This File is 1.a
================

@ -0,0 +1,5 @@
3333333333333333
================
This File is 1.b
================

@ -0,0 +1,5 @@
2222222222222222
================
This File is 2.a
================

@ -0,0 +1,5 @@
3333333333333333
================
This File is 3.a
================

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: com.echo.p2p_project.server.ServerMain

@ -0,0 +1,29 @@
package com.echo.p2p_project;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* @Author: WangYuyang
* @Date: 2021/10/20-17:39
* @Project: P2P_Project
* @Package: com.echo.p2p_project
* @Description:
**/
public class Util {
public static final int RMI_PORT = 1099;
public static String getIP() {
try {
InetAddress ip4 = Inet4Address.getLocalHost();
return ip4.getHostAddress().toString();
} catch (UnknownHostException e) {
e.printStackTrace();
return null;
}
}
}

@ -0,0 +1,451 @@
package com.echo.p2p_project.client;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.net.NetUtil;
import com.echo.p2p_project.Util;
import com.echo.p2p_project.client.interfaces.P2P_FileRegistry;
import com.echo.p2p_project.client.model.CHeartBeat;
import com.echo.p2p_project.client.model.P2PFileImpl;
import com.echo.p2p_project.server.interfaces.ConstructRegistry;
import com.echo.p2p_project.server.interfaces.HeartBeatRegistry;
import com.echo.p2p_project.server.interfaces.HelloRegistryFacade;
import com.echo.p2p_project.server.interfaces.SyncingRegistry;
import com.echo.p2p_project.u_model.Peer;
import com.echo.p2p_project.u_model.Resource;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.rmi.ConnectException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.*;
/**
* @Author: WangYuyang
* @Date: 2021/10/19-15:22
* @Project: P2P_Project
* @Package: com.echo.p2p_project.client
* @Description:
**/
public class ClientMain {
private static final String MainServerIP = "127.0.0.1";
public static Peer peer;
public static HashMap<UUID, Resource> DHRT = new LinkedHashMap();
public static Integer retry_times = 0;
private static String name = "Peer";
private static String IP = Util.getIP();
private static Integer Port = 35000;
private static Integer timeoutMillis = 2000;
private static Registry registry;
private static Registry file_service;
private static ConstructRegistry constructRegistry;
private static HeartBeatRegistry heartBeatRegistry;
private static SyncingRegistry syncingRegistry;
private static Boolean hasStarted = false;
private static Scanner sc;
private static Thread service;
private static Integer download_retry_count = 0;
public static void main(String[] args) throws ConnectException {
service = new Thread(new Runnable() {
@Override
public void run() {
recover();
}
});
service.start();
try {
service.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
sc = new Scanner(System.in);
System.out.println("");
System.out.print(">>> ");
while (sc.hasNextLine()) {
String line = sc.nextLine();
switch (line) {
case "\n":
System.out.print(">>> ");
break;
case "i":
System.out.println("GUID: " + peer.getGUID());
System.out.println("P2P_Port: " + peer.getP2P_port());
System.out.println("Possessing: " + peer.getPossessing());
System.out.println("Possessing Size: " + peer.getPossessing().size());
System.out.println("DHRT: " + DHRT);
break;
case "r":
System.out.print("Register Resource Name: ");
String res_name = sc.nextLine();
reg_file(res_name);
break;
case "l":
System.out.print("Look up Filename: ");
String file_name = sc.nextLine();
HashMap res = look_up_file(file_name);
System.out.println(res);
break;
case "d":
System.out.print("Download Filename: ");
String file_name_to_download = sc.nextLine();
download(file_name_to_download);
}
System.out.print(">>> ");
}
}
private static void download(String file_name_to_download) {
HashMap resources = look_up_file(file_name_to_download);
download(resources);
download_retry_count = 0;
}
private static void download(String file_name_to_download, Integer retry_count) {
if (download_retry_count <= 5) {
download_retry_count+=1;
System.out.println("Retrying " + download_retry_count);
HashMap resources = look_up_file(file_name_to_download);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
download(resources);
}else{
System.out.println("Give up download.");
return;
}
}
public static void init_peer() {
Boolean center_status = false;
Boolean file_status = false;
hasStarted = false;
try {
registry = LocateRegistry.getRegistry(MainServerIP, Util.RMI_PORT);
center_status = lookup_registry() && register_peer() ? true : false;
} catch (RemoteException e) {
// e.printStackTrace();
}
if (peer == null) {
System.out.println("Server Not Running.");
exit();
}
CHeartBeat.StartHeart(heartBeatRegistry, peer.getGUID());
//Init file services
try {
file_service = LocateRegistry.createRegistry(Port);
P2P_FileRegistry p2PFileRegistry = new P2PFileImpl();
file_service.rebind("p2PFileRegistry", p2PFileRegistry);
System.out.println("========== Client-Side RMI Started ! ==========");
System.out.println("Port: " + Port);
System.out.println("UnicastServer: " + file_service.toString());
System.out.println("Registered: " + Arrays.toString(file_service.list()));
System.out.println("===============================================");
//init local file dirs
System.out.println("Download DIR: " + System.getProperty("user.dir") + "/download/");
System.out.println("Resource DIR: " + System.getProperty("user.dir") + "/res/");
FileUtil.mkdir(System.getProperty("user.dir") + "/download/");
FileUtil.mkdir(System.getProperty("user.dir") + "/res/");
file_status = true;
} catch (RemoteException e) {
// e.printStackTrace();
}
if (file_status && center_status)
hasStarted = true;
}
private static Boolean register_peer() {
System.out.println("+++++++ Register & Construct Peer +++++++");
Port = NetUtil.getUsableLocalPort(35000, 45000);
try {
peer = constructRegistry.ConstructPeer(name, IP, Port);
System.out.println("+++++++ Peer Construct Success ! +++++++");
System.out.println("Peer GUID: " + peer.getGUID());
System.out.println("Peer: " + peer);
System.out.println("+++++++ Register Finished +++++++");
return true;
} catch (RemoteException e) {
hasStarted = false;
System.out.println("register_peer RemoteException");
e.printStackTrace();
return false;
}
}
private static Boolean lookup_registry() {
try {
HelloRegistryFacade hello = (HelloRegistryFacade) registry.lookup("HelloRegistry");
String response = hello.helloWorld(name);
System.out.println("=======> " + response + " <=======");
if (response == null) {
System.out.println("server failed");
return false;
}
constructRegistry = (ConstructRegistry) registry.lookup("constructRegistry");
heartBeatRegistry = (HeartBeatRegistry) registry.lookup("heatBeatRegistry");
syncingRegistry = (SyncingRegistry) registry.lookup("syncingRegistry");
return true;
} catch (NotBoundException | RemoteException e) {
System.out.println("lookup_registry RemoteException");
// e.printStackTrace();
return false;
}
}
private static Boolean reg_file(String name) {
File file = new File("res/" + name);
if (!file.exists()) {
System.out.println("File not exists !");
System.out.println("This File is not exist in your file system !");
return false;
} else {
System.out.println("File ok.");
System.out.println("File length: " + file.length());
}
try {
Resource resource = constructRegistry.ConstructResource(peer.getGUID(), name);
ClientMain.DHRT.put(resource.getGUID(), resource);
DHRT.put(resource.getGUID(), resource);
System.out.println("File Register Success!");
System.out.println("Resource GUID: " + resource.getGUID());
sync_peer();
} catch (RemoteException e) {
e.printStackTrace();
System.out.println("File Register Error !");
return false;
}
return true;
}
private static void sync_peer() {
try {
peer = syncingRegistry.syncPeer(peer.getGUID());
} catch (RemoteException e) {
e.printStackTrace();
System.out.println("Peer Sync Failed !");
}
System.out.println("Peer Sync Finished !");
}
private static HashMap<UUID, Resource> look_up_file(String file_name) {
HashMap<UUID, Resource> result = new LinkedHashMap<>();
System.out.println("Looking for: " + file_name);
for (Resource r : DHRT.values()) {
if (r.getName().equals(file_name)) {
System.out.println("FOUND in local DHRT.");
result.put(r.getGUID(), r);
new Thread(new Runnable() {
@Override
public void run() {
try {
DHRT = syncingRegistry.syncUHRT();
System.out.println(Thread.currentThread() + "sync UHRT Finished.");
} catch (RemoteException e) {
e.printStackTrace();
}
}
}).start();
}
}
if (result.size() == 0)
System.out.println("Not found in local DHRT.");
else
return result;
try {
DHRT = syncingRegistry.syncUHRT();
System.out.println("DHRT Sync Finished !");
} catch (RemoteException e) {
e.printStackTrace();
System.out.println("DHRT Sync Failed !");
}
for (Resource r : DHRT.values()) {
if (r.getName().equals(file_name)) {
System.out.println("FOUNT Resource in DHRT (After SYNC REMOTE UHRT)");
result.put(r.getGUID(), r);
}
}
if (result.size() == 0)
System.out.println("Requested Resource NOT FOUND !");
return result;
}
private static void download(HashMap<UUID, Resource> resources) {
if (resources.size() <= 0) {
System.out.println("Resource can not be download !");
return;
}
if (resources.size() > 1) {
System.out.println("There are more than 1 resource with identical name:");
System.out.println("File List: ");
for (Resource r : resources.values()) {
System.out.println(r);
}
System.out.println("Please specify the GUID of the resource: ");
UUID GUID = null;
try {
GUID = UUID.fromString(sc.nextLine());
} catch (IllegalArgumentException e) {
System.out.println("UUID Error");
return;
}
if (GUID == null) {
System.out.println("UUID Error");
return;
}
Resource resource = resources.get(GUID);
if (resource == null) {
System.out.println("Input GUID not in DHRT");
return;
}
Peer p = (Peer) resource.possessedBy.values().stream().sorted().toArray()[0];
P2P_download(p, resource);
} else {
Resource resource = (Resource) resources.values().toArray()[0];
if (resource == null)
return;
Peer p = (Peer) resource.possessedBy.values().stream().sorted().toArray()[0];
P2P_download(p, resource);
}
}
private static void P2P_download(Peer p, Resource resource) {
Integer port = p.getP2P_port();
String IP = p.getIP();
Registry p2pRegistry = null;
File file = null;
try {
p2pRegistry = LocateRegistry.getRegistry(IP, port);
System.out.println("Try to connect: "+ p.getGUID());
P2P_FileRegistry p2PFileRegistry = (P2P_FileRegistry) p2pRegistry.lookup("p2PFileRegistry");
System.out.println("Connected.");
System.out.println("Downloading FROM: " + p.getGUID());
file = p2PFileRegistry.download(resource.getGUID());
} catch (RemoteException e) {
System.out.println("RemoteException");
try {
DHRT = syncingRegistry.syncUHRT();
download(resource.getName(), download_retry_count);
return;
} catch (RemoteException ex) {
ex.printStackTrace();
}
// e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
if (file != null) {
System.out.println("File downloaded !");
System.out.println("File length : " + file.length());
try {
FileUtil.writeToStream(file, new FileOutputStream("download/" + peer.getGUID() + "_FROM_" + p.getGUID() + "_" + resource.getName()));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} else {
System.out.println("P2P_download File Error");
return;
}
}
//
// private static void P2P_download(Peer p, Resource resource, Integer retry_count) {
// retry_count += 1;
// Integer port = p.getP2P_port();
// String IP = p.getIP();
// Registry p2pRegistry = null;
// File file = null;
// try {
// p2pRegistry = LocateRegistry.getRegistry(IP, port);
// P2P_FileRegistry p2PFileRegistry = (P2P_FileRegistry) p2pRegistry.lookup("p2PFileRegistry");
// file = p2PFileRegistry.download(resource.getGUID());
// } catch (RemoteException e) {
// System.out.println("Retry Failed !");
// try {
// DHRT = syncingRegistry.syncUHRT();
// System.out.println("Retrying " + retry_count);
// if (retry_count <= 5) {
// try {
// Thread.sleep(1000);
// } catch (InterruptedException ex) {
// ex.printStackTrace();
// }
// P2P_download(p, resource, retry_count);
// }
// return;
// } catch (RemoteException ex) {
// ex.printStackTrace();
// }
//// e.printStackTrace();
// } catch (NotBoundException e) {
// e.printStackTrace();
// }
// if (file != null) {
// System.out.println("File downloaded !");
// System.out.println("File length : " + file.length());
//
// try {
// FileUtil.writeToStream(file, new FileOutputStream("download/" + peer.getGUID() + "_FROM_" + p.getGUID() + "_" + resource.getName()));
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// }
//
// } else {
// System.out.println("P2P_download File Error");
// return;
// }
//
// }
public static void exit() {
System.exit(0);
}
public static void recover() {
init_peer();
}
public static void recover(int retry_count) {
retry_count += 1;
System.out.println("Try to recover......." + retry_count);
if (retry_count > 10) {
System.out.println();
System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++");
System.out.println("================== CLIENT ====================");
System.out.println("================== SHUTDOWN ====================");
System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++");
System.out.println();
exit();
}
service.interrupt();
service = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
recover();
}
});
service.start();
}
}

@ -0,0 +1,11 @@
package com.echo.p2p_project.client.gui;
/**
* @Author: WangYuyang
* @Date: 2021/10/23-17:11
* @Project: P2P_Project
* @Package: com.echo.p2p_project.client.gui
* @Description:
**/
public class ClientIndexController {
}

@ -0,0 +1,34 @@
package com.echo.p2p_project.client.gui;
import cn.hutool.Hutool;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.Resource;
import cn.hutool.core.io.resource.ResourceUtil;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
/**
* @Author: WangYuyang
* @Date: 2021/10/23-17:11
* @Project: P2P_Project
* @Package: com.echo.p2p_project.client.gui
* @Description:
**/
public class ClientIndexView extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(ResourceUtil.getResource("gui/client_index.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 320, 240);
stage.setTitle("Client!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}

@ -0,0 +1,23 @@
package com.echo.p2p_project.client.gui;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 320, 240);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}

@ -0,0 +1,14 @@
package com.echo.p2p_project.client.gui;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
public class HelloController {
@FXML
private Label welcomeText;
@FXML
protected void onHelloButtonClick() {
welcomeText.setText("Welcome to JavaFX Application!");
}
}

@ -0,0 +1,17 @@
package com.echo.p2p_project.client.interfaces;
import java.io.File;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.UUID;
/**
* @Author: WangYuyang
* @Date: 2021/10/20-21:07
* @Project: P2P_Project
* @Package: com.echo.p2p_project.client.interfaces
* @Description:
**/
public interface P2P_FileRegistry extends Remote {
File download(UUID resID) throws RemoteException;
}

@ -0,0 +1,61 @@
package com.echo.p2p_project.client.model;
import com.echo.p2p_project.client.ClientMain;
import com.echo.p2p_project.server.interfaces.HeartBeatRegistry;
import java.rmi.RemoteException;
import java.util.UUID;
/**
* @Author: WangYuyang
* @Date: 2021/10/20-18:13
* @Project: P2P_Project
* @Package: com.echo.p2p_project.client.model
* @Description:
**/
public class CHeartBeat {
public static Thread heart;
private static Boolean running = true;
public static void StartHeart(HeartBeatRegistry heartBeatRegistry, UUID GUID) {
running = true;
heart = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Start Heart Beat");
while (running) {
try {
Boolean status = heartBeatRegistry.heartBeat(GUID);
// System.out.println(status);
ClientMain.retry_times = 0;
} catch (RemoteException e) {
running = false;
System.out.println("Main Server DOWN !");
ClientMain.retry_times += 1;
ClientMain.recover(ClientMain.retry_times);
// ClientMain.exit();
// System.out.println("Trying to recover...");
// downCount+=1;
// System.out.println("DOWN COUNT: " + downCount);
// if(downCount > 5) {
// System.out.println("DOWN COUNT > 5: Exiting..");
//
// }
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
heart.start();
}
public static void endHeart() {
running = false;
}
}

@ -0,0 +1,50 @@
package com.echo.p2p_project.client.model;
import com.echo.p2p_project.client.ClientMain;
import com.echo.p2p_project.client.interfaces.P2P_FileRegistry;
import com.echo.p2p_project.u_model.Resource;
import java.io.File;
import java.rmi.RemoteException;
import java.rmi.server.RMISocketFactory;
import java.rmi.server.UnicastRemoteObject;
import java.util.UUID;
/**
* @Author: WangYuyang
* @Date: 2021/10/20-21:08
* @Project: P2P_Project
* @Package: com.echo.p2p_project.client.model
* @Description:
**/
public class P2PFileImpl extends UnicastRemoteObject implements P2P_FileRegistry {
/**
* Creates and exports a new UnicastRemoteObject object using an
* anonymous port.
*
* <p>The object is exported with a server socket
* created using the {@link RMISocketFactory} class.
*
* @throws RemoteException if failed to export object
* @since JDK1.1
*/
public P2PFileImpl() throws RemoteException {
super();
}
@Override
public File download(UUID resID) throws RemoteException{
Resource resource = ClientMain.DHRT.get(resID);
if(resource == null){
System.out.println("Resource Not in local DHRT.");
return null;
}
File file = new File("res/" + resource.getName());
if (file==null) {
System.out.println("Resource Not in File System.");
return null;
}
return file;
}
}

@ -0,0 +1,108 @@
package com.echo.p2p_project.server;
import com.echo.p2p_project.Util;
import com.echo.p2p_project.server.interfaces.ConstructRegistry;
import com.echo.p2p_project.server.interfaces.HeartBeatRegistry;
import com.echo.p2p_project.server.interfaces.HelloRegistryFacade;
import com.echo.p2p_project.server.interfaces.SyncingRegistry;
import com.echo.p2p_project.server.model.*;
import com.echo.p2p_project.u_model.Peer;
import com.echo.p2p_project.u_model.Resource;
import com.sun.javafx.collections.ObservableMapWrapper;
import javafx.collections.ObservableMap;
import java.io.PrintStream;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.*;
/**
* @Author: WangYuyang
* @Date: 2021/10/19-15:22
* @Project: P2P_Project
* @Package: com.echo.p2p_project.server
* @Description:
**/
public class ServerMain{
public static ObservableMapWrapper<UUID, Peer> UHPT = new ObservableMapWrapper<>(new LinkedHashMap<>());
public static ObservableMapWrapper<UUID, Resource> UHRT = new ObservableMapWrapper<>(new LinkedHashMap<>());
private static Registry registry;
private static Boolean HasStarted = false;
private static Thread service;
public static void main(String[] args) {
service = new Thread(new Runnable() {
@Override
public void run() {
init();
}
});
service.start();
Scanner sc = new Scanner(System.in);
System.out.println("");
System.out.print(">>> ");
while (sc.hasNextLine()) {
String line = sc.nextLine();
switch (line) {
case "\n":
System.out.print(">>> ");
break;
case "i":
System.out.println("UHPT: " + UHPT);
System.out.println("UHPT Size: " + UHPT.size());
System.out.println("UHRT: " + UHRT);
System.out.println("UHRT Size: " + UHRT.size());
System.out.println("registry: " + registry);
break;
}
System.out.print(">>> ");
}
}
public static void init() {
try {
// Start Registry, Port: 1099
registry = LocateRegistry.createRegistry(Util.RMI_PORT);
reg_services();
System.out.println("======= RMI Start Up! ============");
System.out.println(registry.toString());
System.out.println("Registered: " + Arrays.toString(registry.list()));
for (String s : registry.list()) {
System.out.println("Registered: " + s);
}
System.out.println("============ WatchDog ============");
if (!HasStarted)
WatchDog.startWatchDog();
System.out.println("======= Start Up Finished ========");
HasStarted = true;
} catch (RemoteException e) {
e.printStackTrace();
}
}
private static void reg_services() {
try {
HelloRegistryFacade hello = new HelloRegistryFacadeImpl();
ConstructRegistry constructRegistry = new ConstructImpl();
HeartBeatRegistry heartBeatRegistry = new HeartBeatImpl();
SyncingRegistry syncingRegistry = new SyncingImpl();
registry.rebind("HelloRegistry", hello);
registry.rebind("constructRegistry", constructRegistry);
registry.rebind("heatBeatRegistry", heartBeatRegistry);
registry.rebind("syncingRegistry", syncingRegistry);
} catch (RemoteException e) {
e.printStackTrace();
}
}
public static void exit(){
service.interrupt();
}
}

@ -0,0 +1,78 @@
package com.echo.p2p_project.server.gui;
import cn.hutool.core.io.resource.ResourceUtil;
import com.echo.p2p_project.server.ServerMain;
import javafx.application.Application;
import javafx.collections.MapChangeListener;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.TableView;
import javafx.scene.control.TextArea;
import javafx.scene.control.TreeView;
import javafx.stage.Stage;
import java.io.IOException;
/**
* @Author: WangYuyang
* @Date: 2021/10/23-17:20
* @Project: P2P_Project
* @Package: com.echo.p2p_project.server.gui
* @Description:
**/
public class ServerIndexApplication extends Application {
private static Thread server_thread;
private static Thread log_thread;
private static Boolean is_started = false;
// public static ObservableMap O_UHPT;
// public static ObservableMap O_UHRT;
public static void main(String[] args) {
launch();
}
public static void init_server() {
if (is_started == false) {
is_started = true;
server_thread = new Thread(new Runnable() {
@Override
public void run() {
ServerMain.main(new String[]{});
}
});
server_thread.start();
} else {
System.out.println("CAN NOT START");
}
}
public static void stopServer() {
if (is_started) {
ServerMain.exit();
server_thread.interrupt();
is_started = false;
System.exit(0);
}
}
public static void start_log(TextArea logField, TableView uhpt_table, TableView uhrt_table, TreeView uhrt_tree) {
// log_thread = new Thread(new Runnable() {
// @Override
// public void run() {
//
// }
// });
// log_thread.start();
}
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(ResourceUtil.getResource("gui/server_index.fxml"));
Scene scene = new Scene(fxmlLoader.load());
stage.setTitle("Server");
stage.setScene(scene);
stage.show();
}
}

@ -0,0 +1,152 @@
package com.echo.p2p_project.server.gui;
import com.echo.p2p_project.server.ServerMain;
import com.echo.p2p_project.u_model.Peer;
import com.echo.p2p_project.u_model.Resource;
import com.sun.javafx.collections.ObservableListWrapper;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.MapChangeListener;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.scene.control.*;
import javafx.util.Callback;
import java.util.ArrayList;
/**
* @Author: WangYuyang
* @Date: 2021/10/23-17:21
* @Project: P2P_Project
* @Package: com.echo.p2p_project.server.gui
* @Description:
**/
public class ServerIndexController {
public Button StartServerButton;
public TextArea LogField;
public Button StopServerButton;
public TableView<Peer> uhpt_table;
public TableView<Resource> uhrt_table;
public TreeView uhrt_tree;
public TableColumn<Peer, String> UHPT_GUID;
public TableColumn<Peer, String> UHPT_IP;
public TableColumn<Peer, String> UHPT_PORT;
public TableColumn<Resource, String> UHRT_GUID;
public TableColumn<Resource, String> UHRT_NAME;
public void initialize() {
UHPT_GUID.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Peer, String>, ObservableValue<String>>() {
@Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Peer, String> param) {
return new SimpleStringProperty(param.getValue().getGUID().toString());
}
});
UHPT_IP.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Peer, String>, ObservableValue<String>>() {
@Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Peer, String> param) {
return new SimpleStringProperty(param.getValue().getIP().toString());
}
});
UHPT_PORT.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Peer, String>, ObservableValue<String>>() {
@Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Peer, String> param) {
return new SimpleStringProperty(param.getValue().getP2P_port().toString());
}
});
UHRT_GUID.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Resource, String>, ObservableValue<String>>() {
@Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Resource, String> param) {
return new SimpleStringProperty(param.getValue().getGUID().toString());
}
});
UHRT_NAME.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Resource, String>, ObservableValue<String>>() {
@Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Resource, String> param) {
return new SimpleStringProperty(param.getValue().getName().toString());
}
});
ServerMain.UHPT.addListener(new MapChangeListener() {
@Override
public void onChanged(Change change) {
Platform.runLater(new Runnable() {
@Override
public void run() {
//update log
LogField.appendText(change.toString() + "\n\n");
//update table
ObservableList<Peer> peers = new ObservableListWrapper<Peer>(new ArrayList<>(ServerMain.UHPT.values()));
uhpt_table.setItems(peers);
//update tree
TreeItem<String> rootItem = new TreeItem<String>("Server");
rootItem.setExpanded(true);
for (Peer p : peers) {
TreeItem<String> item = new TreeItem<String>(p.getGUID().toString());
for (Resource r : p.possessing.values()) {
item.setExpanded(true);
TreeItem<String> filename = new TreeItem<String>(r.getName().toString());
item.getChildren().add(filename);
}
rootItem.getChildren().add(item);
}
uhrt_tree.setRoot(rootItem);
}
});
}
});
ServerMain.UHRT.addListener(new MapChangeListener() {
@Override
public void onChanged(Change change) {
Platform.runLater(new Runnable() {
@Override
public void run() {
//update log
LogField.appendText(change.toString() + "\n\n");
//update table
ObservableList<Resource> resources = new ObservableListWrapper<Resource>(new ArrayList<>(ServerMain.UHRT.values()));
uhrt_table.setItems(resources);
//update tree
ObservableList<Peer> peers = new ObservableListWrapper<Peer>(new ArrayList<>(ServerMain.UHPT.values()));
TreeItem<String> rootItem = new TreeItem<String>("Server");
rootItem.setExpanded(true);
for (Peer p : peers) {
TreeItem<String> item = new TreeItem<String>(p.getGUID().toString());
for (Resource r : p.possessing.values()) {
item.setExpanded(true);
TreeItem<String> filename = new TreeItem<String>(r.getName().toString());
item.getChildren().add(filename);
}
rootItem.getChildren().add(item);
}
uhrt_tree.setRoot(rootItem);
}
});
}
});
}
public void StartServerButtonPressed(ActionEvent actionEvent) {
ServerIndexApplication.init_server();
}
public void StopServerButtonPressed(ActionEvent actionEvent) {
ServerIndexApplication.stopServer();
}
}

@ -0,0 +1,20 @@
package com.echo.p2p_project.server.interfaces;
import com.echo.p2p_project.u_model.Peer;
import com.echo.p2p_project.u_model.Resource;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.UUID;
/**
* @Author: WangYuyang
* @Date: 2021/10/20-17:09
* @Project: P2P_Project
* @Package: com.echo.p2p_project.server.interfaces
* @Description:
**/
public interface ConstructRegistry extends Remote {
Peer ConstructPeer(String name, String IP, Integer P2P_port) throws RemoteException;
Resource ConstructResource(UUID PeerGUID, String name) throws RemoteException;
}

@ -0,0 +1,16 @@
package com.echo.p2p_project.server.interfaces;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.UUID;
/**
* @Author: WangYuyang
* @Date: 2021/10/20-17:48
* @Project: P2P_Project
* @Package: com.echo.p2p_project.server.interfaces
* @Description:
**/
public interface HeartBeatRegistry extends Remote {
Boolean heartBeat(UUID GUID) throws RemoteException;
}

@ -0,0 +1,15 @@
package com.echo.p2p_project.server.interfaces;
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
* @Author: WangYuyang
* @Date: 2021/10/20-16:37
* @Project: P2P_Project
* @Package: com.echo.p2p_project.server.interfaces
* @Description:
**/
public interface HelloRegistryFacade extends Remote {
String helloWorld(String name) throws RemoteException;
}

@ -0,0 +1,20 @@
package com.echo.p2p_project.server.interfaces;
import com.echo.p2p_project.u_model.Peer;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.UUID;
/**
* @Author: WangYuyang
* @Date: 2021/10/20-22:45
* @Project: P2P_Project
* @Package: com.echo.p2p_project.server.interfaces
* @Description:
**/
public interface SyncingRegistry extends Remote {
Peer syncPeer(UUID GUID) throws RemoteException;
HashMap syncUHRT() throws RemoteException;
}

@ -0,0 +1,79 @@
package com.echo.p2p_project.server.model;
import com.echo.p2p_project.server.ServerMain;
import com.echo.p2p_project.server.interfaces.ConstructRegistry;
import com.echo.p2p_project.u_model.Peer;
import com.echo.p2p_project.u_model.Resource;
import java.rmi.RemoteException;
import java.rmi.server.RMISocketFactory;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.Random;
import java.util.UUID;
/**
* @Author: WangYuyang
* @Date: 2021/10/20-17:10
* @Project: P2P_Project
* @Package: com.echo.p2p_project.server.model
* @Description:
**/
public class ConstructImpl extends UnicastRemoteObject implements ConstructRegistry {
/**
* Creates and exports a new UnicastRemoteObject object using an
* anonymous port.
*
* <p>The object is exported with a server socket
* created using the {@link RMISocketFactory} class.
*
* @throws RemoteException if failed to export object
* @since JDK1.1
*/
public ConstructImpl() throws RemoteException {
super();
}
@Override
public Peer ConstructPeer(String name, String IP_Address, Integer P2P_port) throws RemoteException {
UUID GUID = UUID.randomUUID();
if(ServerMain.UHPT.containsKey(GUID)) {
System.out.println("DUP GUID!!!!!!!");
return null;
}
String peerName = name;
String IP = IP_Address;
Integer port = P2P_port;
Random random = new Random();
Integer routingMetric = random.nextInt(100);
Peer peer = new Peer(GUID, peerName, IP, port, routingMetric);
ServerMain.UHPT.put(peer.getGUID(), peer);
System.out.println("Peer Reg: " + peer);
return peer;
}
@Override
public Resource ConstructResource(UUID PeerGUID, String name) throws RemoteException {
Peer peer = ServerMain.UHPT.get(PeerGUID);
//If peer not registered in center
if(peer == null)
return null; // Res register failed
UUID GUID = UUID.randomUUID();
//If duplicated GUID
if(ServerMain.UHPT.containsKey(GUID)) {
System.out.println("DUP GUID!!!!!!!");
return null; // Res register failed
}
String ResName = name;
Resource res = new Resource(GUID, ResName);
res.possessedBy.put(peer.getGUID(), peer);
ServerMain.UHRT.put(res.getGUID(), res);
ServerMain.UHPT.get(peer.getGUID()).possessing.put(res.getGUID(), res);
System.out.println("Resources Registered: " + res);
return res;
}
}

@ -0,0 +1,42 @@
package com.echo.p2p_project.server.model;
import com.echo.p2p_project.server.ServerMain;
import com.echo.p2p_project.server.interfaces.HeartBeatRegistry;
import com.echo.p2p_project.u_model.Peer;
import java.rmi.RemoteException;
import java.rmi.server.RMISocketFactory;
import java.rmi.server.UnicastRemoteObject;
import java.util.UUID;
/**
* @Author: WangYuyang
* @Date: 2021/10/20-17:49
* @Project: P2P_Project
* @Package: com.echo.p2p_project.server.model
* @Description:
**/
public class HeartBeatImpl extends UnicastRemoteObject implements HeartBeatRegistry {
/**
* Creates and exports a new UnicastRemoteObject object using an
* anonymous port.
*
* <p>The object is exported with a server socket
* created using the {@link RMISocketFactory} class.
*
* @throws RemoteException if failed to export object
* @since JDK1.1
*/
public HeartBeatImpl() throws RemoteException {
super();
}
@Override
public Boolean heartBeat(UUID GUID) throws RemoteException {
Peer peer = ServerMain.UHPT.get(GUID);
if(peer == null)
return false;
peer.setMissedHartBeat(0);
return true;
}
}

@ -0,0 +1,39 @@
package com.echo.p2p_project.server.model;
import com.echo.p2p_project.server.interfaces.HelloRegistryFacade;
import java.rmi.RemoteException;
import java.rmi.server.RMISocketFactory;
import java.rmi.server.UnicastRemoteObject;
/**
* @Author: WangYuyang
* @Date: 2021/10/20-16:38
* @Project: P2P_Project
* @Package: com.echo.p2p_project.server.model
* @Description:
**/
public class HelloRegistryFacadeImpl extends UnicastRemoteObject implements HelloRegistryFacade {
/**
* Creates and exports a new UnicastRemoteObject object using an
* anonymous port.
*
* <p>The object is exported with a server socket
* created using the {@link RMISocketFactory} class.
*
* @throws RemoteException if failed to export object
* @since JDK1.1
*/
public HelloRegistryFacadeImpl() throws RemoteException {
super();
System.out.println("HelloRegistryFacadeImpl");
}
@Override
public String helloWorld(String name) {
return "[Registry] Hi, " + name;
}
}

@ -0,0 +1,53 @@
package com.echo.p2p_project.server.model;
import com.echo.p2p_project.server.ServerMain;
import com.echo.p2p_project.server.interfaces.SyncingRegistry;
import com.echo.p2p_project.u_model.Peer;
import java.rmi.RemoteException;
import java.rmi.server.RMISocketFactory;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.UUID;
/**
* @Author: WangYuyang
* @Date: 2021/10/20-22:45
* @Project: P2P_Project
* @Package: com.echo.p2p_project.server.model
* @Description:
**/
public class SyncingImpl extends UnicastRemoteObject implements SyncingRegistry {
/**
* Creates and exports a new UnicastRemoteObject object using an
* anonymous port.
*
* <p>The object is exported with a server socket
* created using the {@link RMISocketFactory} class.
*
* @throws RemoteException if failed to export object
* @since JDK1.1
*/
public SyncingImpl() throws RemoteException {
super();
}
@Override
public Peer syncPeer(UUID GUID) throws RemoteException{
Peer peer = ServerMain.UHPT.get(GUID);
if (peer==null)
return null;
return peer;
}
@Override
public HashMap syncUHRT() throws RemoteException {
HashMap hashMap = new LinkedHashMap();
for (UUID key: ServerMain.UHRT.keySet()) {
hashMap.put(key, ServerMain.UHRT.get(key));
}
HashMap map = hashMap;
return map;
}
}

@ -0,0 +1,63 @@
package com.echo.p2p_project.server.model;
import com.echo.p2p_project.server.ServerMain;
import com.echo.p2p_project.u_model.Peer;
import com.echo.p2p_project.u_model.Resource;
import java.util.UUID;
/**
* @Author: WangYuyang
* @Date: 2021/10/20-17:52
* @Project: P2P_Project
* @Package: com.echo.p2p_project.server.model
* @Description:
**/
public class WatchDog {
private static Thread watch_thread;
private static Boolean running = true;
public static void startWatchDog() {
watch_thread = new Thread(new Runnable() {
@Override
public void run() {
while (running) {
for (int i = 0; i < ServerMain.UHPT.size(); i++) {
UUID uuid = (UUID) ServerMain.UHPT.keySet().toArray()[i];
Peer p = ServerMain.UHPT.get(uuid);
// System.out.println(p);
if (p == null) {
System.out.println("REMOVED(peer is null): " + uuid);
ServerMain.UHPT.remove(uuid);
continue;
}
p.setMissedHartBeat(p.getMissedHartBeat() + 1);
if (p.getMissedHartBeat() > 5) {
System.out.println();
System.out.println("==================================== REMOVE =====================================");
System.out.println("PEER (peer MissedHartBeat > 5): " + uuid);
for (UUID guid : ServerMain.UHPT.get(uuid).possessing.keySet()) {
System.out.println("Resources: " + guid);
ServerMain.UHRT.remove(guid);
}
ServerMain.UHPT.remove(uuid);
System.out.println("=================================================================================");
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("WatchDog Interrupted");
}
}
}
});
watch_thread.start();
System.out.println("WatchDog Started !");
}
public static void stopWatchDog() {
running = false;
// watch_thread.interrupt();
}
}

@ -0,0 +1,151 @@
package com.echo.p2p_project.u_model;
import cn.hutool.Hutool;
import com.sun.istack.internal.NotNull;
import java.io.Serializable;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.UUID;
/**
* @Author: WangYuyang
* @Date: 2021/10/19-15:23
* @Project: P2P_Project
* @Package: com.echo.p2p_project.u_model
* @Description:
**/
public class Peer implements Serializable,Comparable {
private UUID GUID;
private String name;
private String IP;
private Integer P2P_port;
private Integer routingMetric;
private Integer MissedHartBeat = 0;
//Only use this possessing in DHRT
public HashMap<UUID, Resource> possessing = new LinkedHashMap();
public Peer(UUID GUID, String name, String IP, Integer p2P_port, Integer routingMetric) {
this.GUID = GUID;
this.name = name;
this.IP = IP;
P2P_port = p2P_port;
this.routingMetric = routingMetric;
}
public UUID getGUID() {
return GUID;
}
public void setGUID(UUID GUID) {
this.GUID = GUID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIP() {
return IP;
}
public void setIP(String IP) {
this.IP = IP;
}
public Integer getP2P_port() {
return P2P_port;
}
public void setP2P_port(Integer p2P_port) {
P2P_port = p2P_port;
}
public Integer getRoutingMetric() {
return routingMetric;
}
public void setRoutingMetric(Integer routingMetric) {
this.routingMetric = routingMetric;
}
public HashMap<UUID, Resource> getPossessing() {
return possessing;
}
public void setPossessing(HashMap<UUID, Resource> possessing) {
this.possessing = possessing;
}
public Integer getMissedHartBeat() {
return MissedHartBeat;
}
public void setMissedHartBeat(Integer missedHartBeat) {
MissedHartBeat = missedHartBeat;
}
@Override
public String toString() {
return "Peer{" +
"GUID=" + GUID +
", name='" + name + '\'' +
", IP='" + IP + '\'' +
", P2P_port=" + P2P_port +
", routingMetric=" + routingMetric +
", MissedHartBeat=" + MissedHartBeat +
", possessing=" + possessing.keySet() +
'}';
}
/**
* Compares this object with the specified object for order. Returns a
* negative integer, zero, or a positive integer as this object is less
* than, equal to, or greater than the specified object.
*
* <p>The implementor must ensure <tt>sgn(x.compareTo(y)) ==
* -sgn(y.compareTo(x))</tt> for all <tt>x</tt> and <tt>y</tt>. (This
* implies that <tt>x.compareTo(y)</tt> must throw an exception iff
* <tt>y.compareTo(x)</tt> throws an exception.)
*
* <p>The implementor must also ensure that the relation is transitive:
* <tt>(x.compareTo(y)&gt;0 &amp;&amp; y.compareTo(z)&gt;0)</tt> implies
* <tt>x.compareTo(z)&gt;0</tt>.
*
* <p>Finally, the implementor must ensure that <tt>x.compareTo(y)==0</tt>
* implies that <tt>sgn(x.compareTo(z)) == sgn(y.compareTo(z))</tt>, for
* all <tt>z</tt>.
*
* <p>It is strongly recommended, but <i>not</i> strictly required that
* <tt>(x.compareTo(y)==0) == (x.equals(y))</tt>. Generally speaking, any
* class that implements the <tt>Comparable</tt> interface and violates
* this condition should clearly indicate this fact. The recommended
* language is "Note: this class has a natural ordering that is
* inconsistent with equals."
*
* <p>In the foregoing description, the notation
* <tt>sgn(</tt><i>expression</i><tt>)</tt> designates the mathematical
* <i>signum</i> function, which is defined to return one of <tt>-1</tt>,
* <tt>0</tt>, or <tt>1</tt> according to whether the value of
* <i>expression</i> is negative, zero or positive.
*
* @param o the object to be compared.
* @return a negative integer, zero, or a positive integer as this object
* is less than, equal to, or greater than the specified object.
* @throws NullPointerException if the specified object is null
* @throws ClassCastException if the specified object's type prevents it
* from being compared to this object.
*/
@Override
public int compareTo(@NotNull Object o) {
Peer p = (Peer) o;
return p.routingMetric - p.routingMetric;
}
}

@ -0,0 +1,57 @@
package com.echo.p2p_project.u_model;
import java.io.Serializable;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.UUID;
/**
* @Author: WangYuyang
* @Date: 2021/10/20-16:57
* @Project: P2P_Project
* @Package: com.echo.p2p_project.u_model
* @Description:
**/
public class Resource implements Serializable {
private UUID GUID;
private String name;
public HashMap<UUID, Peer> possessedBy = new LinkedHashMap<>();
public Resource(UUID GUID, String name) {
this.GUID = GUID;
this.name = name;
}
public UUID getGUID() {
return GUID;
}
public void setGUID(UUID GUID) {
this.GUID = GUID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public HashMap<UUID, Peer> getPossessedBy() {
return possessedBy;
}
public void setPossessedBy(HashMap<UUID, Peer> possessedBy) {
this.possessedBy = possessedBy;
}
@Override
public String toString() {
return "Resource{" +
"GUID=" + GUID +
", name='" + name + '\'' +
", possessedBy=" + possessedBy.keySet() +
'}';
}
}

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="com.echo.p2p_project.client.gui.ClientIndexController"
prefHeight="400.0" prefWidth="600.0">
</AnchorPane>

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.echo.p2p_project.client.gui.ClientIndexController">
<children>
<VBox prefHeight="451.0" prefWidth="679.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<Button mnemonicParsing="false" text="Button" />
</children>
</VBox>
</children>
</AnchorPane>

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.echo.p2p_project.server.gui.ServerIndexController">
<children>
<VBox>
<children>
<HBox alignment="CENTER">
<children>
<VBox alignment="CENTER" spacing="16.0">
<children>
<Label text="Server Controls" />
<Button fx:id="StartServerButton" mnemonicParsing="false" onAction="#StartServerButtonPressed" prefHeight="27.0" prefWidth="102.0" text="Start Server" />
<Button fx:id="StopServerButton" mnemonicParsing="false" onAction="#StopServerButtonPressed" prefHeight="27.0" prefWidth="102.0" text="Stop Server" />
</children>
<padding>
<Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
</padding>
<HBox.margin>
<Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
</HBox.margin>
</VBox>
<VBox alignment="CENTER" spacing="8.0">
<children>
<Label text="Log" />
<TextArea fx:id="LogField" maxHeight="150.0" prefHeight="150.0" prefWidth="676.0" wrapText="true">
<font>
<Font name="Andale Mono" size="9.0" />
</font></TextArea>
</children>
<padding>
<Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
</padding>
</VBox>
</children>
</HBox>
<HBox alignment="CENTER">
<children>
<VBox alignment="CENTER">
<children>
<Label text="UHPT" />
<TableView fx:id="uhpt_table">
<columns>
<TableColumn fx:id="UHPT_GUID" prefWidth="114.0" text="GUID" />
<TableColumn fx:id="UHPT_IP" prefWidth="115.0" text="IP" />
<TableColumn fx:id="UHPT_PORT" prefWidth="115.0" text="PORT" />
</columns>
</TableView>
</children>
<padding>
<Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
</padding>
</VBox>
<VBox alignment="CENTER">
<children>
<Label text="UHRT" />
<TableView fx:id="uhrt_table">
<columns>
<TableColumn fx:id="UHRT_GUID" prefWidth="128.0" text="GUID" />
<TableColumn fx:id="UHRT_NAME" prefWidth="115.0" text="NAME" />
</columns>
</TableView>
</children>
<padding>
<Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
</padding>
</VBox>
<VBox alignment="CENTER">
<children>
<Label text="UHRT Tree" />
<TreeView fx:id="uhrt_tree" />
</children>
<padding>
<Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
</padding>
</VBox>
</children>
<padding>
<Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
</padding>
</HBox>
</children>
</VBox>
</children>
</AnchorPane>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="com.echo.p2p_project.client.gui.ClientIndexController"
prefHeight="400.0" prefWidth="600.0">
</AnchorPane>

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.echo.p2p_project.client.gui.ClientIndexController">
<children>
<VBox prefHeight="451.0" prefWidth="679.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<Button mnemonicParsing="false" text="Button" />
</children>
</VBox>
</children>
</AnchorPane>

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.echo.p2p_project.server.gui.ServerIndexController">
<children>
<VBox>
<children>
<HBox alignment="CENTER">
<children>
<VBox alignment="CENTER" spacing="16.0">
<children>
<Label text="Server Controls" />
<Button fx:id="StartServerButton" mnemonicParsing="false" onAction="#StartServerButtonPressed" prefHeight="27.0" prefWidth="102.0" text="Start Server" />
<Button fx:id="StopServerButton" mnemonicParsing="false" onAction="#StopServerButtonPressed" prefHeight="27.0" prefWidth="102.0" text="Stop Server" />
</children>
<padding>
<Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
</padding>
<HBox.margin>
<Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
</HBox.margin>
</VBox>
<VBox alignment="CENTER" spacing="8.0">
<children>
<Label text="Log" />
<TextArea fx:id="LogField" maxHeight="150.0" prefHeight="150.0" prefWidth="676.0" wrapText="true">
<font>
<Font name="Andale Mono" size="9.0" />
</font></TextArea>
</children>
<padding>
<Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
</padding>
</VBox>
</children>
</HBox>
<HBox alignment="CENTER">
<children>
<VBox alignment="CENTER">
<children>
<Label text="UHPT" />
<TableView fx:id="uhpt_table">
<columns>
<TableColumn fx:id="UHPT_GUID" prefWidth="114.0" text="GUID" />
<TableColumn fx:id="UHPT_IP" prefWidth="115.0" text="IP" />
<TableColumn fx:id="UHPT_PORT" prefWidth="115.0" text="PORT" />
</columns>
</TableView>
</children>
<padding>
<Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
</padding>
</VBox>
<VBox alignment="CENTER">
<children>
<Label text="UHRT" />
<TableView fx:id="uhrt_table">
<columns>
<TableColumn fx:id="UHRT_GUID" prefWidth="128.0" text="GUID" />
<TableColumn fx:id="UHRT_NAME" prefWidth="115.0" text="NAME" />
</columns>
</TableView>
</children>
<padding>
<Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
</padding>
</VBox>
<VBox alignment="CENTER">
<children>
<Label text="UHRT Tree" />
<TreeView fx:id="uhrt_tree" />
</children>
<padding>
<Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
</padding>
</VBox>
</children>
<padding>
<Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
</padding>
</HBox>
</children>
</VBox>
</children>
</AnchorPane>
Loading…
Cancel
Save