CurtisWalsh 4 years ago
parent
commit
d23d1bdc99
41 changed files with 1001 additions and 381 deletions
  1. 8 0
      .idea/.gitignore
  2. 10 0
      .idea/libraries/lib.xml
  3. 1 1
      .idea/modules.xml
  4. 124 0
      .idea/uiDesigner.xml
  5. 6 0
      .idea/vcs.xml
  6. 135 45
      .idea/workspace.xml
  7. 0 3
      OneToOne.properties
  8. BIN
      lib/mysql-connector-java-8.0.20.jar
  9. BIN
      out/production/OneToOne/ClientChatMain.class
  10. BIN
      out/production/OneToOne/ServerChatMain.class
  11. BIN
      out/production/talktalk/1.png
  12. BIN
      out/production/talktalk/Client$1.class
  13. BIN
      out/production/talktalk/Client$2.class
  14. BIN
      out/production/talktalk/Client$3.class
  15. BIN
      out/production/talktalk/Client$4.class
  16. BIN
      out/production/talktalk/Client.class
  17. BIN
      out/production/talktalk/LoginFrame$1.class
  18. BIN
      out/production/talktalk/LoginFrame.class
  19. BIN
      out/production/talktalk/LoginResult.class
  20. BIN
      out/production/talktalk/MessageResult.class
  21. BIN
      out/production/talktalk/Server$1$1.class
  22. BIN
      out/production/talktalk/Server$1.class
  23. BIN
      out/production/talktalk/Server$2.class
  24. BIN
      out/production/talktalk/Server$3.class
  25. BIN
      out/production/talktalk/Server$4.class
  26. BIN
      out/production/talktalk/Server$TalkUser.class
  27. BIN
      out/production/talktalk/Server.class
  28. BIN
      out/production/talktalk/Sqlconn.class
  29. 3 0
      out/production/talktalk/startClient.bat
  30. BIN
      src/1.png
  31. 164 0
      src/Client.java
  32. 0 162
      src/ClientChatMain.java
  33. 120 0
      src/LoginFrame.java
  34. 30 0
      src/LoginResult.java
  35. 74 0
      src/MessageResult.java
  36. 279 0
      src/Server.java
  37. 0 170
      src/ServerChatMain.java
  38. 42 0
      src/Sqlconn.java
  39. 3 0
      src/startClient.bat
  40. 1 0
      talktalk.iml
  41. 1 0
      users.sql

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/../../../../../../:\Users\MHL\IdeaProjects\talktalk\.idea/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/

+ 10 - 0
.idea/libraries/lib.xml

@@ -0,0 +1,10 @@
+<component name="libraryTable">
+  <library name="lib">
+    <CLASSES>
+      <root url="file://$PROJECT_DIR$/lib" />
+    </CLASSES>
+    <JAVADOC />
+    <SOURCES />
+    <jarDirectory url="file://$PROJECT_DIR$/lib" recursive="false" />
+  </library>
+</component>

+ 1 - 1
.idea/modules.xml

@@ -2,7 +2,7 @@
 <project version="4">
   <component name="ProjectModuleManager">
     <modules>
-      <module fileurl="file://$PROJECT_DIR$/OneToOne.iml" filepath="$PROJECT_DIR$/OneToOne.iml" />
+      <module fileurl="file://$PROJECT_DIR$/talktalk.iml" filepath="$PROJECT_DIR$/talktalk.iml" />
     </modules>
   </component>
 </project>

+ 124 - 0
.idea/uiDesigner.xml

@@ -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>

+ 6 - 0
.idea/vcs.xml

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

+ 135 - 45
.idea/workspace.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="ChangeListManager">
-    <list default="true" id="a967317c-7b81-4f6a-b7e9-51cdaf77c31b" name="Default Changelist" comment="" />
+    <list default="true" id="ea5dbc31-138f-46f3-ab4a-4b9de63a9cfb" name="Default Changelist" comment="" />
     <option name="SHOW_DIALOG" value="false" />
     <option name="HIGHLIGHT_CONFLICTS" value="true" />
     <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
@@ -13,66 +13,117 @@
   <component name="FileTemplateManagerImpl">
     <option name="RECENT_TEMPLATES">
       <list>
+        <option value="Interface" />
         <option value="Class" />
       </list>
     </option>
   </component>
+  <component name="Git.Settings">
+    <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
+  </component>
+  <component name="MavenImportPreferences">
+    <option name="generalSettings">
+      <MavenGeneralSettings>
+        <option name="mavenHome" value="D:\Program Files\JetBrains\IntelliJ IDEA 2019.3.3\plugins\maven\lib\maven3" />
+      </MavenGeneralSettings>
+    </option>
+  </component>
   <component name="ProjectCodeStyleSettingsMigration">
     <option name="version" value="1" />
   </component>
-  <component name="ProjectId" id="1lzdhQWgZ3MTTc2jERQKKo6FK3L" />
+  <component name="ProjectId" id="1lxSZyJG4TzW7T02TQTvmXIN4qn" />
   <component name="ProjectViewState">
-    <option name="showExcludedFiles" value="true" />
+    <option name="hideEmptyMiddlePackages" value="true" />
     <option name="showLibraryContents" value="true" />
   </component>
   <component name="PropertiesComponent">
+    <property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
     <property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
     <property name="WebServerToolWindowFactoryState" value="false" />
     <property name="aspect.path.notification.shown" value="true" />
-    <property name="last_opened_file_path" value="$PROJECT_DIR$/../多人聊天+用户在线" />
-    <property name="settings.editor.selected.configurable" value="editor.preferences.fonts.default" />
+    <property name="last_opened_file_path" value="$PROJECT_DIR$" />
+    <property name="project.structure.last.edited" value="Libraries" />
+    <property name="project.structure.proportion" value="0.0" />
+    <property name="project.structure.side.proportion" value="0.2321839" />
   </component>
-  <component name="RunManager" selected="Application.ClientChatMain">
-    <configuration name="ClientChatMain" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
-      <option name="MAIN_CLASS_NAME" value="ClientChatMain" />
-      <module name="OneToOne" />
+  <component name="RecentsManager">
+    <key name="ExtractSuperBase.RECENT_KEYS">
+      <recent name="run" />
+    </key>
+  </component>
+  <component name="RunManager" selected="Application.LoginFrame">
+    <configuration name="Client" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
+      <option name="MAIN_CLASS_NAME" value="Client" />
+      <module name="talktalk" />
+      <method v="2">
+        <option name="Make" enabled="true" />
+      </method>
+    </configuration>
+    <configuration name="LoginFrame" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
+      <option name="MAIN_CLASS_NAME" value="LoginFrame" />
+      <module name="talktalk" />
+      <method v="2">
+        <option name="Make" enabled="true" />
+      </method>
+    </configuration>
+    <configuration name="Server" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
+      <option name="MAIN_CLASS_NAME" value="Server" />
+      <module name="talktalk" />
       <method v="2">
         <option name="Make" enabled="true" />
       </method>
     </configuration>
-    <configuration name="ServerChatMain" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
-      <option name="MAIN_CLASS_NAME" value="ServerChatMain" />
-      <module name="OneToOne" />
+    <configuration name="test" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
+      <option name="MAIN_CLASS_NAME" value="test" />
+      <module name="talktalk" />
       <method v="2">
         <option name="Make" enabled="true" />
       </method>
     </configuration>
     <recent_temporary>
       <list>
-        <item itemvalue="Application.ClientChatMain" />
-        <item itemvalue="Application.ServerChatMain" />
+        <item itemvalue="Application.LoginFrame" />
+        <item itemvalue="Application.Server" />
+        <item itemvalue="Application.test" />
+        <item itemvalue="Application.Client" />
       </list>
     </recent_temporary>
   </component>
+  <component name="SpellCheckerSettings" BundledDictionaries="0" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" Dictionaries="0" CorrectionsLimit="5" DefaultDictionary="application-level" UseSingleDictionary="true" />
   <component name="SvnConfiguration">
     <configuration />
   </component>
   <component name="TaskManager">
     <task active="true" id="Default" summary="Default task">
-      <changelist id="a967317c-7b81-4f6a-b7e9-51cdaf77c31b" name="Default Changelist" comment="" />
-      <created>1608603972443</created>
+      <changelist id="ea5dbc31-138f-46f3-ab4a-4b9de63a9cfb" name="Default Changelist" comment="" />
+      <created>1608537309192</created>
       <option name="number" value="Default" />
       <option name="presentableId" value="Default" />
-      <updated>1608603972443</updated>
-      <workItem from="1608603975890" duration="2481000" />
-      <workItem from="1608606905181" duration="943000" />
-      <workItem from="1608684253226" duration="18264000" />
-      <workItem from="1608792815791" duration="44000" />
-      <workItem from="1608857593367" duration="1122000" />
-      <workItem from="1609125120242" duration="5702000" />
-      <workItem from="1609289263576" duration="622000" />
-      <workItem from="1609292747184" duration="579000" />
-      <workItem from="1609293541541" duration="602000" />
+      <updated>1608537309192</updated>
+      <workItem from="1608537310298" duration="12364000" />
+      <workItem from="1608597121592" duration="10133000" />
+      <workItem from="1608615127712" duration="4845000" />
+      <workItem from="1608621151102" duration="22076000" />
+      <workItem from="1608683378420" duration="8504000" />
+      <workItem from="1608722603591" duration="9686000" />
+      <workItem from="1608769984619" duration="6753000" />
+      <workItem from="1608787433050" duration="3296000" />
+      <workItem from="1608894821542" duration="2000" />
+      <workItem from="1608895724757" duration="1349000" />
+      <workItem from="1608963724868" duration="3575000" />
+      <workItem from="1609050347731" duration="16187000" />
+      <workItem from="1609116288158" duration="4361000" />
+      <workItem from="1609130924809" duration="101000" />
+      <workItem from="1609156455402" duration="7646000" />
+      <workItem from="1609202126531" duration="14467000" />
+      <workItem from="1609245887865" duration="9340000" />
+      <workItem from="1609288913013" duration="8092000" />
+      <workItem from="1609308715349" duration="2321000" />
+      <workItem from="1609318992228" duration="6418000" />
+      <workItem from="1609329075378" duration="321000" />
+      <workItem from="1609331880519" duration="3372000" />
+      <workItem from="1609376219413" duration="40000" />
+      <workItem from="1609376284492" duration="232000" />
     </task>
     <servers />
   </component>
@@ -80,38 +131,77 @@
     <option name="version" value="1" />
   </component>
   <component name="WindowStateProjectService">
-    <state x="574" y="121" key="#com.intellij.ide.util.MemberChooser" timestamp="1608772025746">
-      <screen x="0" y="0" width="1536" height="824" />
+    <state x="574" y="122" key="#com.intellij.ide.util.MemberChooser" timestamp="1609310439285">
+      <screen x="0" y="0" width="1536" height="834" />
     </state>
-    <state x="574" y="121" key="#com.intellij.ide.util.MemberChooser/0.0.1536.824@0.0.1536.824" timestamp="1608772025746" />
-    <state x="549" y="170" key="FileChooserDialogImpl" timestamp="1609293326070">
+    <state x="574" y="122" key="#com.intellij.ide.util.MemberChooser/0.0.1536.834@0.0.1536.834" timestamp="1609310439285" />
+    <state x="549" y="170" key="FileChooserDialogImpl" timestamp="1609376236737">
       <screen x="0" y="0" width="1536" height="824" />
     </state>
-    <state x="549" y="170" key="FileChooserDialogImpl/0.0.1536.824@0.0.1536.824" timestamp="1609293326070" />
-    <state width="1493" height="210" key="GridCell.Tab.0.bottom" timestamp="1609296452720">
+    <state x="549" y="170" key="FileChooserDialogImpl/0.0.1536.824@0.0.1536.824" timestamp="1609376236737" />
+    <state x="549" y="172" key="FileChooserDialogImpl/0.0.1536.834@0.0.1536.834" timestamp="1609326661849" />
+    <state width="1493" height="210" key="GridCell.Tab.0.bottom" timestamp="1609376517301">
       <screen x="0" y="0" width="1536" height="824" />
     </state>
-    <state width="1493" height="210" key="GridCell.Tab.0.bottom/0.0.1536.824@0.0.1536.824" timestamp="1609296452720" />
-    <state width="1493" height="210" key="GridCell.Tab.0.center" timestamp="1609296452720">
+    <state width="1493" height="210" key="GridCell.Tab.0.bottom/0.0.1536.824@0.0.1536.824" timestamp="1609376517301" />
+    <state width="1493" height="160" key="GridCell.Tab.0.bottom/0.0.1536.834@0.0.1536.834" timestamp="1609344509655" />
+    <state width="1493" height="210" key="GridCell.Tab.0.center" timestamp="1609376517301">
       <screen x="0" y="0" width="1536" height="824" />
     </state>
-    <state width="1493" height="210" key="GridCell.Tab.0.center/0.0.1536.824@0.0.1536.824" timestamp="1609296452720" />
-    <state width="1493" height="210" key="GridCell.Tab.0.left" timestamp="1609296452719">
+    <state width="1493" height="210" key="GridCell.Tab.0.center/0.0.1536.824@0.0.1536.824" timestamp="1609376517301" />
+    <state width="1493" height="160" key="GridCell.Tab.0.center/0.0.1536.834@0.0.1536.834" timestamp="1609344509655" />
+    <state width="1493" height="210" key="GridCell.Tab.0.left" timestamp="1609376517301">
       <screen x="0" y="0" width="1536" height="824" />
     </state>
-    <state width="1493" height="210" key="GridCell.Tab.0.left/0.0.1536.824@0.0.1536.824" timestamp="1609296452719" />
-    <state width="1493" height="210" key="GridCell.Tab.0.right" timestamp="1609296452720">
+    <state width="1493" height="210" key="GridCell.Tab.0.left/0.0.1536.824@0.0.1536.824" timestamp="1609376517301" />
+    <state width="1493" height="160" key="GridCell.Tab.0.left/0.0.1536.834@0.0.1536.834" timestamp="1609344509655" />
+    <state width="1493" height="210" key="GridCell.Tab.0.right" timestamp="1609376517301">
       <screen x="0" y="0" width="1536" height="824" />
     </state>
-    <state width="1493" height="210" key="GridCell.Tab.0.right/0.0.1536.824@0.0.1536.824" timestamp="1609296452720" />
-    <state x="-123" y="29" key="SettingsEditor" timestamp="1608607843212">
-      <screen x="0" y="0" width="1536" height="824" />
+    <state width="1493" height="210" key="GridCell.Tab.0.right/0.0.1536.824@0.0.1536.824" timestamp="1609376517301" />
+    <state width="1493" height="160" key="GridCell.Tab.0.right/0.0.1536.834@0.0.1536.834" timestamp="1609344509655" />
+    <state width="1478" height="261" key="GridCell.Tab.1.bottom" timestamp="1608896653449">
+      <screen x="0" y="0" width="1536" height="834" />
     </state>
-    <state x="-123" y="29" key="SettingsEditor/0.0.1536.824@0.0.1536.824" timestamp="1608607843212" />
-    <state x="431" y="145" width="672" height="678" key="search.everywhere.popup" timestamp="1608687549237">
-      <screen x="0" y="0" width="1536" height="824" />
+    <state width="1478" height="261" key="GridCell.Tab.1.bottom/0.0.1536.834@0.0.1536.834" timestamp="1608896653449" />
+    <state width="1478" height="261" key="GridCell.Tab.1.center" timestamp="1608896653449">
+      <screen x="0" y="0" width="1536" height="834" />
+    </state>
+    <state width="1478" height="261" key="GridCell.Tab.1.center/0.0.1536.834@0.0.1536.834" timestamp="1608896653449" />
+    <state width="1478" height="261" key="GridCell.Tab.1.left" timestamp="1608896653449">
+      <screen x="0" y="0" width="1536" height="834" />
+    </state>
+    <state width="1478" height="261" key="GridCell.Tab.1.left/0.0.1536.834@0.0.1536.834" timestamp="1608896653449" />
+    <state width="1478" height="261" key="GridCell.Tab.1.right" timestamp="1608896653449">
+      <screen x="0" y="0" width="1536" height="834" />
     </state>
-    <state x="431" y="145" width="672" height="678" key="search.everywhere.popup/0.0.1536.824@0.0.1536.824" timestamp="1608687549237" />
+    <state width="1478" height="261" key="GridCell.Tab.1.right/0.0.1536.834@0.0.1536.834" timestamp="1608896653449" />
+    <state x="349" y="160" key="IDE.errors.dialog" timestamp="1608537656612">
+      <screen x="0" y="0" width="1536" height="834" />
+    </state>
+    <state x="349" y="160" key="IDE.errors.dialog/0.0.1536.834@0.0.1536.834" timestamp="1608537656612" />
+    <state x="249" y="0" key="SettingsEditor" timestamp="1609326665571">
+      <screen x="0" y="0" width="1536" height="834" />
+    </state>
+    <state x="249" y="0" key="SettingsEditor/0.0.1536.834@0.0.1536.834" timestamp="1609326665571" />
+    <state x="306" y="153" width="924" height="641" key="com.intellij.xdebugger.impl.breakpoints.ui.BreakpointsDialogFactory$2" timestamp="1608687589999">
+      <screen x="0" y="0" width="1536" height="834" />
+    </state>
+    <state x="306" y="153" width="924" height="641" key="com.intellij.xdebugger.impl.breakpoints.ui.BreakpointsDialogFactory$2/0.0.1536.834@0.0.1536.834" timestamp="1608687589999" />
+    <state x="319" y="155" width="672" height="678" key="search.everywhere.popup" timestamp="1609251036174">
+      <screen x="0" y="0" width="1536" height="834" />
+    </state>
+    <state x="319" y="155" width="672" height="678" key="search.everywhere.popup/0.0.1536.834@0.0.1536.834" timestamp="1609251036174" />
+  </component>
+  <component name="XDebuggerManager">
+    <breakpoint-manager>
+      <breakpoints>
+        <breakpoint enabled="true" type="java-exception">
+          <properties class="java.lang.NullPointerException" package="java.lang" />
+          <option name="timeStamp" value="1" />
+        </breakpoint>
+      </breakpoints>
+    </breakpoint-manager>
   </component>
   <component name="se.expertsystem.intellij.aop.aspectj.AspectJProjectComponent">
     <setting name="isActivated" value="false" />

+ 0 - 3
OneToOne.properties

@@ -1,3 +0,0 @@
-serverPort=8888
-clientIp=127.0.0.1
-clientPort=8888

BIN
lib/mysql-connector-java-8.0.20.jar


BIN
out/production/OneToOne/ClientChatMain.class


BIN
out/production/OneToOne/ServerChatMain.class


BIN
out/production/talktalk/1.png


BIN
out/production/talktalk/Client$1.class


BIN
out/production/talktalk/Client$2.class


BIN
out/production/talktalk/Client$3.class


BIN
out/production/talktalk/Client$4.class


BIN
out/production/talktalk/Client.class


BIN
out/production/talktalk/LoginFrame$1.class


BIN
out/production/talktalk/LoginFrame.class


BIN
out/production/talktalk/LoginResult.class


BIN
out/production/talktalk/MessageResult.class


BIN
out/production/talktalk/Server$1$1.class


BIN
out/production/talktalk/Server$1.class


BIN
out/production/talktalk/Server$2.class


BIN
out/production/talktalk/Server$3.class


BIN
out/production/talktalk/Server$4.class


BIN
out/production/talktalk/Server$TalkUser.class


BIN
out/production/talktalk/Server.class


BIN
out/production/talktalk/Sqlconn.class


+ 3 - 0
out/production/talktalk/startClient.bat

@@ -0,0 +1,3 @@
+javac LoginFrame.java -encoding UTF-8
+java LoginFrame
+del *.class

BIN
src/1.png


+ 164 - 0
src/Client.java

@@ -0,0 +1,164 @@
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+
+public class Client extends JFrame {
+    private JList<String> jList;
+    private DefaultListModel<String> model;
+    private JTextField enterField;
+    private JButton sendButton;
+    private JButton closeButton;
+    private JTextArea displayArea;
+    private ObjectOutputStream output;
+    private ObjectInputStream input;
+    private String message = "";
+    /**
+     * 生成通讯界面。
+     * enterField用于发送对话。布局displayArea用于显示
+     * 聊天信息。监听enterField,收到的字符串通过调用
+     * sendData(String message)发送到客户端。
+     */
+
+    public Client(ObjectOutputStream oop,ObjectInputStream oip) throws IOException, ClassNotFoundException {
+        JPanel jp1=new JPanel();
+        jp1.setLayout(new FlowLayout());
+        JPanel jp2=new JPanel();
+        jp2.setLayout(new FlowLayout());
+        output=oop;
+        input=oip;
+        setBounds(500, 600, 650, 600);
+        setTitle("TalkTalkClient");
+        setDefaultCloseOperation(EXIT_ON_CLOSE);
+
+        jList=new JList<>();
+        model=new DefaultListModel<>();
+        model.addElement("ALL");
+        jList.setModel(model);
+        jList.setSelectedIndex(0);
+        JScrollPane jsp=new JScrollPane(jList);
+
+        displayArea = new JTextArea();
+        displayArea.setFont(new Font("微软雅黑",Font.PLAIN,16));
+        displayArea.setLineWrap(true);
+        displayArea.setPreferredSize(new Dimension(500,500));
+        displayArea.setEditable(false);
+        jsp.setPreferredSize(new Dimension(100,500));
+        jp1.add(displayArea, BorderLayout.WEST);
+        jp1.add(jsp, BorderLayout.EAST);
+
+        add(jp1,BorderLayout.NORTH);
+        setIconImage(Toolkit.getDefaultToolkit().getImage(LoginFrame.class.getResource("/1.png")));
+        enterField=new JTextField(20);
+        enterField.setFont(new Font("微软雅黑",Font.PLAIN,20));
+        sendButton=new JButton("发送");
+        closeButton=new JButton("关闭");
+        jp2.add(enterField, BorderLayout.EAST);
+        jp2.add(sendButton, BorderLayout.CENTER);
+        jp2.add(closeButton, BorderLayout.WEST);
+        add(jp2,BorderLayout.SOUTH);
+        validate();
+        //创建一个线程反复读取服务端的消息
+        new Thread(){
+            @Override
+            public void run() {
+                try {
+                    startc();
+                } catch (IOException | ClassNotFoundException e) {
+                    e.printStackTrace();
+                }
+            }
+        }.start();
+
+        setVisible(true);
+        //监听发送按钮
+        sendButton.addActionListener(new java.awt.event.ActionListener() {
+            String toUser=jList.getSelectedValue();
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                try {
+                    message = enterField.getText();
+                    enterField.setText(null);
+                    sendData(new MessageResult(3,message,toUser));
+                } catch (IOException ioException) {
+                    JOptionPane.showMessageDialog(new JFrame(), "服务器连接异常");
+                }
+            }
+        });
+        //监听关闭按钮
+        closeButton.addActionListener(new java.awt.event.ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                try {
+                    sendData(new MessageResult(2,"null","null"));
+                    System.exit(0);
+                } catch (IOException ignored) {
+
+                }
+            }
+        });
+        //监听窗口关闭
+        addWindowListener(new WindowAdapter() {
+            @Override
+            public void windowClosing(WindowEvent e) {
+                try {
+                    sendData(new MessageResult(2,"null","null"));
+                    System.exit(0);
+                } catch (IOException ignored) {
+                }
+
+            }
+        });
+
+
+
+    }
+
+    //读取服务端发来的消息并显示到displayArea
+    public void startc() throws IOException, ClassNotFoundException {
+        ArrayList<String> userlist;
+        while(true) {
+            MessageResult messageResult =  (MessageResult) input.readObject();
+            String text= messageResult.getMessage();
+
+            int type= messageResult.getType();
+
+            if (type==5){
+                System.out.println(messageResult.getUserList());
+                addUser(messageResult.getUserList());
+            }
+            if (text.equals("TERMINATE")) {
+                break;
+            }
+            if(text.equals("NULL")|text.equals("null")){continue;}
+            displayArea.append(text);
+        }
+    }
+    /**
+     * 把message写到数据输出流,即发送到服务端。并显示在 displayArea中。
+     * @param message 从界面的enterField对象接收到的字符串。
+     */
+    private void sendData( MessageResult message ) throws IOException {
+//        把message发送到服务端
+        output.writeObject(message);
+        output.flush();
+        if (message.getType()==3){
+            displayArea.append("你说:"+message.getMessage()+"\n");
+        }
+    }
+
+    private void addUser(ArrayList<String> name){
+        model.removeAllElements();
+
+        for (String s : name) {
+            model.addElement(s);
+        }
+//            jList.setModel(model);
+    }
+}

+ 0 - 162
src/ClientChatMain.java

@@ -1,162 +0,0 @@
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.KeyEvent;
-import java.awt.event.KeyListener;
-import java.io.*;
-import java.net.Socket;
-import java.util.Properties;
-
-//说明:如果一个类,需要有界面的显示,那么这个类就需要继承JFrame。此时,该类就可以被称为 “ 窗体类 ” 。
-//1.定义窗体中的组件。
-//2.在构造方法中初始化窗体的组件。
-//3.使用网络编程完成数据的传输(TCP,UDP协议)。
-//4.实现 “ 发送 ” 按钮的监听点击事件。需要注意的是,文本拼接数据时实现自己换行,不要在发送数据中使用System.lineSeparator()换行。
-//这样会导致bw.newLine() 与 System.lineSeparator() 两个换行,导致使用BufferedWriter一行一行读取时无法正确的辨别需要的换行。
-//5.实现回车键发送数据。
-public class ClientChatMain extends JFrame implements ActionListener , KeyListener {
-    public static void main(String[] args) {
-        //调用构造方法
-        new ClientChatMain();
-    }
-    //属性
-    //文本域
-    private JTextArea jta;
-    //滚动条
-    private JScrollPane jsp;
-    //面板
-    private JPanel jp;
-    //文本框
-    private JTextField jtf;
-    //按钮
-    private JButton jb;
-
-    //输出流
-    private BufferedWriter bw = null;
-
-    //客户端的 Ip 地址
-    private static String clientIp;
-    //客户端的端口号
-    private static int clientPort;
-
-    //静态代码块加载外部配置文件
-    static {
-        Properties prop = new Properties();
-        try {
-            prop.load(new FileReader("OneToOne.properties"));
-            clientIp = prop.getProperty("clientIp");
-            clientPort = Integer.parseInt(prop.getProperty("clientPort"));
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    //构造方法
-    public ClientChatMain() {
-        //初始化组件
-        //文本域
-        jta = new JTextArea();
-        //设置文本域不可编辑
-        jta.setEditable(false);
-        //滚动条  注意:需要将文本域添加到滚动条中,实现滚动效果。
-        jsp = new JScrollPane(jta);
-        //面板
-        jp = new JPanel();
-        //文本框  需要给长度
-        jtf= new JTextField(10);
-        //按钮  需要写按钮功能
-        jb = new JButton("发送");
-        //注意:需要将文本框和按钮添加到面板中
-        jp.add(jtf);
-        jp.add(jb);
-
-        //注意:需要将滚动条与面板添加到窗体中,并设置布局。
-        this.add(jsp, BorderLayout.CENTER);
-        this.add(jp,BorderLayout.SOUTH);
-
-        //注意:需要设置 “ 标题,大小,位置,关闭,是否可见 ”
-        this.setTitle("OneToOne聊天 客户端");
-        this.setSize(500,500);
-        this.setLocation(1000,300);
-        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-        this.setVisible(true);
-
-        /*********************** TCP 客户端 start ***********************/
-        //给发送按钮绑定一个监听点击事件
-        jb.addActionListener(this);
-        //给文本框绑定键盘点击事件
-        jtf.addKeyListener(this);
-        try{
-        //1.创建一个客户端的套接字(尝试链接)
-        Socket socket = new Socket(clientIp,clientPort);
-
-        //2.获取 Socket 通道的输入流
-        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
-
-        //3.获取 Socket 通道的输出流
-        bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
-
-        //循环读取数据并拼接到文本域中
-        String line = null;
-        while ((line = br.readLine()) != null){
-            jta.append(line + System.lineSeparator());
-        }
-
-        //4.关闭 Socket 通道
-        socket.close();
-
-    }catch (Exception e){
-        e.printStackTrace();
-    }
-
-        /*********************** TCP 客户端 end  ***********************/
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent e) {
-        sendDataToSocket();
-    }
-
-    //行为
-
-    @Override
-    public void keyPressed(KeyEvent e) {
-        //回车键
-        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
-            System.out.println(e);
-            //发送数据到 socket 通道中
-            sendDataToSocket();
-        }
-    }
-
-    //定义一个方法,实现将数据发送到 socket 通道中
-    private void sendDataToSocket(){
-        //1.获取文本框中发送的内容
-        String text = jtf.getText();
-        //2.拼接需要发送的数据内容
-        text = "服务端对客户端说:" + text ;
-        //3.发送之前自己显示
-        jta.append(text + System.lineSeparator());
-        try {
-            //4.发送
-            bw.write(text);
-            bw.newLine();
-            bw.flush();
-            //5.清空文本框内容
-            jtf.setText("");
-        } catch (IOException ex) {
-            ex.printStackTrace();
-        }
-    }
-
-    @Override
-    public void keyTyped(KeyEvent e) {
-    }
-
-    @Override
-    public void keyReleased(KeyEvent e) {
-    }
-
-
-}

+ 120 - 0
src/LoginFrame.java

@@ -0,0 +1,120 @@
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.Socket;
+
+public class LoginFrame extends JFrame{
+    private JTextField id;
+    private JPasswordField pwd;
+    private Socket socket;
+    private ObjectOutputStream oos;
+    private ObjectInputStream ois;
+
+    public LoginFrame() {
+
+        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        setVisible(true);
+        setIconImage(Toolkit.getDefaultToolkit().getImage(LoginFrame.class.getResource("/1.png")));
+        Toolkit tk=Toolkit.getDefaultToolkit();
+        Dimension d=tk.getScreenSize();
+        int x=(int)(d.getWidth()-379)/2;
+        int y=(int)(d.getHeight()-171)/2;
+        setResizable(false);
+        setTitle("\u767B\u5F55");
+        setBounds(x, y, 379, 171);
+        getContentPane().setLayout(new GridLayout(3, 1, 20, 5));
+
+        JPanel panel = new JPanel();
+        getContentPane().add(panel);
+        FlowLayout fl_panel = new FlowLayout(FlowLayout.CENTER, 5, 10);
+        fl_panel.setAlignOnBaseline(true);
+        panel.setLayout(fl_panel);
+
+        JLabel label = new JLabel("用户帐号:");
+        label.setFont(new Font("微软雅黑", Font.PLAIN, 15));
+        panel.add(label);
+
+        id = new JTextField();
+        panel.add(id);
+        id.setColumns(15);
+
+
+        JPanel panel_1 = new JPanel();
+        FlowLayout flowLayout = (FlowLayout) panel_1.getLayout();
+        flowLayout.setAlignOnBaseline(true);
+        flowLayout.setVgap(10);
+        getContentPane().add(panel_1);
+
+        JLabel label_1 = new JLabel("用户密码:");
+        label_1.setFont(new Font("微软雅黑", Font.PLAIN, 15));
+        panel_1.add(label_1);
+
+        pwd = new JPasswordField();
+        pwd.setColumns(15);
+        panel_1.add(pwd);
+
+        JPanel panel_2 = new JPanel();
+        FlowLayout flowLayout_1 = (FlowLayout) panel_2.getLayout();
+        flowLayout_1.setVgap(6);
+        getContentPane().add(panel_2);
+
+        JButton button = new JButton("登录");
+        ActionListener actionListener = new ActionListener() {
+            public void actionPerformed(ActionEvent arg0) {
+                String username = id.getText().trim();
+                String password = new String(pwd.getPassword());
+                String cmd=arg0.getActionCommand();
+
+                if ("".equals(username) || "".equals(password)) {
+                    JOptionPane.showMessageDialog(new JFrame(), "用户名和密码不能为空");
+                } else {
+                    try {
+                        socket = new Socket("127.0.0.1", 9090);
+                        oos = new ObjectOutputStream(socket.getOutputStream());
+                        MessageResult mr;
+                        oos.flush();
+                        ois = new ObjectInputStream(socket.getInputStream());
+
+                        if (cmd.equals("登录")){
+                            oos.writeObject(new MessageResult(1,new LoginResult(username,password)));
+                            mr=(MessageResult)ois.readObject();
+                            System.out.println(mr.getMessage());
+                            if (mr.getMessage().equals("LOGINSUCCESS")){
+                                dispose();
+                                new Client(oos,ois);
+                            }else {JOptionPane.showMessageDialog(new JFrame(), "用户名或密码错误!");}
+                        }
+
+                        if (cmd.equals("注册")){
+                            oos.writeObject(new MessageResult(0,new LoginResult(username,password)));
+                            mr=(MessageResult)ois.readObject();
+                            if (mr.getMessage().equals("SIGNUPSUCCESS")){
+                                JOptionPane.showMessageDialog(new JFrame(), "注册成功!");socket.close();
+                            }else {JOptionPane.showMessageDialog(new JFrame(), "注册失败!");socket.close();}
+                        }
+
+                    } catch (IOException | ClassNotFoundException e) {
+                        JOptionPane.showMessageDialog(new JFrame(), "服务器连接异常");
+                    }
+                }
+            }
+        };
+        button.addActionListener(actionListener);
+        button.setFont(new Font("微软雅黑", Font.PLAIN, 15));
+        panel_2.add(button);
+
+        JButton button_1 = new JButton("注册");
+        button_1.addActionListener(actionListener);
+        button_1.setFont(new Font("微软雅黑", Font.PLAIN, 15));
+        panel_2.add(button_1);
+        setVisible(true);
+    }
+
+    public static void main(String[] args) {
+        new LoginFrame();
+    }
+}

+ 30 - 0
src/LoginResult.java

@@ -0,0 +1,30 @@
+import java.io.Serializable;
+
+public class LoginResult implements Serializable {
+    private String id;
+    private String pw;
+
+    public LoginResult() {
+    }
+
+    public LoginResult(String id, String pw) {
+        this.id = id;
+        this.pw = pw;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getPw() {
+        return pw;
+    }
+
+    public void setPw(String pw) {
+        this.pw = pw;
+    }
+}

+ 74 - 0
src/MessageResult.java

@@ -0,0 +1,74 @@
+import java.io.Serializable;
+import java.util.ArrayList;
+
+public class MessageResult implements Serializable {
+    /**
+     * 0 注册信息
+     * 1 登录信息
+     * 2 退出信息
+     * 3 聊天信息
+     * 4 私密消息
+     */
+    private int type;
+    private String message;
+    private String to;
+    private LoginResult lr;
+    private ArrayList<String> userList;
+    public MessageResult() {
+    }
+
+    public MessageResult(int type, String message,String to) {
+        this.type = type;
+        this.message = message;
+        this.to=to;
+    }
+    public MessageResult(int type,LoginResult lr) {
+        this.type = type;
+        this.lr=lr;
+    }
+    public MessageResult(int type, ArrayList<String> userList,String message) {
+        this.type = type;
+        this.userList=userList;
+        this.message=message;
+    }
+
+    public int getType() {
+        return type;
+    }
+
+    public void setType(int type) {
+        this.type = type;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public LoginResult getLr() {
+        return lr;
+    }
+
+    public void setLr(LoginResult lr) {
+        this.lr = lr;
+    }
+
+    public String getTo() {
+        return to;
+    }
+
+    public void setTo(String to) {
+        this.to = to;
+    }
+
+    public ArrayList<String> getUserList() {
+        return userList;
+    }
+
+    public void setUserList(ArrayList<String> userList) {
+        this.userList = userList;
+    }
+}

+ 279 - 0
src/Server.java

@@ -0,0 +1,279 @@
+import javax.swing.*;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+
+public class Server extends JFrame {
+    private String toUser="1";
+
+    private JList<String> jList=null;
+    private DefaultListModel<String> model;
+    private ArrayList<String> userList=new ArrayList<>();
+    private JButton startButton;
+    private JButton stopButton;
+    private ServerSocket server;
+    private Socket socket;
+    private boolean stopflag=false;//是否停止服务标识
+    //保存每个客户端的输出流
+    private static HashMap<Socket,ObjectOutputStream> users=new HashMap<>();
+    //保存每个客户端的用户名
+    private static HashMap<Socket,String> username=new HashMap<>();
+
+    private int counter = 0;
+    /**
+     * 生成服务端通讯界面。
+     */
+    public Server(){
+        userList.add("ALL");
+        JPanel jp1=new JPanel();
+        jp1.setLayout(null);
+        JPanel jp2=new JPanel();
+        jp2.setLayout(null);
+        setBounds(700, 300, 500, 500);
+        jList=new JList<>();
+        model=new DefaultListModel<>();
+        model.addElement("ALL");
+        jList.setModel(model);
+        jList.setSelectedIndex(0);
+        JScrollPane jsp=new JScrollPane(jList);
+        jsp.setBounds(370, 10, 100, 250);
+        setVisible(true);
+        setTitle("TalkTalkServer");
+        setDefaultCloseOperation(EXIT_ON_CLOSE);
+        startButton = new JButton("启动");
+        stopButton = new JButton("停止");
+
+        startButton.setBounds(10,10,60,45);
+        stopButton.setBounds(80,10,60,45);
+        stopButton.setEnabled(false);
+        add(jsp);
+        jp1.add(startButton);
+        jp1.add(stopButton);
+//        JTextField enterField=new JTextField(10);
+//        enterField.setFont(new Font("微软雅黑",Font.PLAIN,18));
+//        jp2.setBounds(10,80,20,20);
+//        jp2.add(enterField);
+        add(jp1);
+
+//        validate();
+
+        // 监听[启动]和[停止]按钮和响应程序
+        startButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                new Thread(){
+                    @Override
+                    public void run() {
+                        try {
+                            startHandler(evt);
+                        } catch (IOException e) {
+                            e.printStackTrace();
+                        }
+                    }
+                }.start();
+            }
+        });
+
+        stopButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                try {
+                    stopHandler(evt);
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        });
+    }
+
+    class TalkUser extends Thread {
+        Sqlconn sql=new Sqlconn();
+        private Socket s;
+        private ObjectOutputStream output;
+        private ObjectInputStream input;
+
+        private String message;
+        public TalkUser(Socket s) throws IOException {
+            this.s = s;
+            this.input = new ObjectInputStream(s.getInputStream());
+            users.put(s,new ObjectOutputStream(s.getOutputStream()));
+        }
+        @Override
+        public void run() {
+            /* 在循环中,反复
+             * 利用Socket s接收并处理消息,直到用户退出或出错。
+             */
+            try {
+                while (true) {
+                    //用输入流读客户端消息;
+                    MessageResult messageResult=(MessageResult)input.readObject();
+                    //注册
+
+                    if(messageResult.getType()==0){
+                        boolean loginFlag = sql.signup((messageResult.getLr()).getId(), (messageResult.getLr()).getPw());
+                        if(loginFlag){sendToUsers(4,new MessageResult(4,"SIGNUPSUCCESS","null"));
+                        }else {
+                            sendToUsers(4,new MessageResult(4,"SIGNUPFAIL","null"));
+                        }
+                        users.remove(s);
+                        s.close();
+                        break;
+                    }
+                    //登录
+                    if(messageResult.getType()==1){
+                        boolean loginFlag = sql.login((messageResult.getLr()).getId(), (messageResult.getLr()).getPw());
+                        if (loginFlag){
+                            sendToUsers(4,new MessageResult(4,"LOGINSUCCESS","null"));
+                        }else {
+                            sendToUsers(4,new MessageResult(4,"LOGINFAIL","null"));
+                            users.remove(s);
+                            break;
+                        }
+                        userList.add((messageResult.getLr()).getId());
+                        username.put(s,(messageResult.getLr()).getId());
+                        addUser(userList);
+                        System.out.println(userList);
+                        sendToUsers(5,new MessageResult(5,userList,"NULL"));
+                        sendToUsers(1,new MessageResult(1,"系统消息:@"+username.get(s)+"登录成功\r\n","null"));
+                    }
+                    //退出登录
+                    if(messageResult.getType()==2){
+                        sendToUsers(4,new MessageResult(4,"TERMINATE","null"));
+
+                        sendToUsers(1,new MessageResult(1,"系统消息:@"+username.get(s)+"退出登录\r\n","null"));
+
+                        users.remove(s);
+                        userList.remove(username.get(s));
+                        username.remove(s);
+                        addUser(userList);
+                        sendToUsers(5,new MessageResult(5,userList,"NULL"));
+                        s.close();
+                        break;
+                    }
+                    //聊天
+                    if(messageResult.getType()==3){
+                        toUser=messageResult.getTo();
+                        message =messageResult.getMessage();
+                        sendToUsers(3,new MessageResult(3,s.getInetAddress()+"@"+username.get(s)+":"+message+"\r\n","null"));
+                    }
+
+                }
+            } catch (IOException | ClassNotFoundException | SQLException e) {
+                e.printStackTrace();
+
+            }finally {
+                try {
+                    s.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+
+
+        }
+        //添加到在线用户列表
+        private void addUser(ArrayList<String> name){
+            model.removeAllElements();
+
+            for (String s : name) {
+                model.addElement(s);
+            }
+//            jList.setModel(model);
+        }
+
+
+        public void sendToUsers(int type,MessageResult message) throws IOException {
+
+            for (Socket s :users.keySet()){
+                //聊天信息,发给除了自己的其他人
+                if (type==3&s==this.s){
+                    continue;
+                }
+                //只发给自己,登录和退出消息
+                if (type==4&!(s==this.s)){
+                    continue;
+                }
+
+                ObjectOutputStream w=users.get(s);
+                w.writeObject(message);
+                w.flush();
+            }
+
+        }
+    }
+
+
+
+
+    private void start() throws IOException {
+        //建立一个TalkUser对象TalkUser,用9090端口进行通讯
+        server= new ServerSocket(9090,100);
+        while ( true ) {
+            //等待客户端连接
+            socket = server.accept();
+            //如果已经停止服务,退出循环
+            if (getStopflag()){
+                break;
+            }
+//            创建一个user并保存在users中;
+            new TalkUser(socket).start();
+
+            //创建一个TalkUser线程,用socket和该客户通讯
+//            递增counter;
+            counter++;
+        }
+    }
+
+    private void stop() throws IOException {
+        //建立一个本地socket来跳出accept阻塞
+        new Socket("127.0.0.1",9090);
+
+        server.close();
+        users.clear();
+        username.clear();
+    }
+
+
+
+
+    private void startHandler(java.awt.event.ActionEvent evt) throws IOException {
+        setStopflag(false);
+
+        java.awt.EventQueue.invokeLater(new Runnable() {
+            public void run() {
+                startButton.setEnabled(false);
+                stopButton.setEnabled(true);
+
+            }
+        });
+        start();
+    }
+
+    private void stopHandler(java.awt.event.ActionEvent evt) throws IOException {
+        setStopflag(true);
+        stop();
+        java.awt.EventQueue.invokeLater(new Runnable() {
+            public void run() {
+                startButton.setEnabled(true);
+                stopButton.setEnabled(false);
+
+            }
+        });
+    }
+
+    private void setStopflag(boolean flag){
+        stopflag=flag;
+    }
+    private boolean getStopflag() {
+        return stopflag;
+    }
+
+    public static void main(String[] args) {
+        new Server();
+    }
+
+}

+ 0 - 170
src/ServerChatMain.java

@@ -1,170 +0,0 @@
-import javax.swing.*;
-import javax.xml.soap.Text;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.KeyEvent;
-import java.awt.event.KeyListener;
-import java.io.*;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.Properties;
-
-//说明:如果一个类,需要有界面的显示,那么这个类就需要继承JFrame。此时,该类就可以被称为 “ 窗体类 ” 。
-//1.定义窗体中的组件。
-//2.在构造方法中初始化窗体的组件。
-//3.使用网络编程完成数据的传输(TCP,UDP协议)。
-//4.实现 “ 发送 ” 按钮的监听点击事件。需要注意的是,文本拼接数据时实现自己换行,不要在发送数据中使用System.lineSeparator()换行。
-//这样会导致bw.newLine() 与 System.lineSeparator() 两个换行,导致使用BufferedWriter一行一行读取时无法正确的辨别需要的换行。
-//5.实现回车键发送数据。
-public class ServerChatMain extends JFrame implements ActionListener , KeyListener {
-    public static void main(String[] args) {
-        //调用构造方法
-        new ServerChatMain();
-    }
-    //属性
-    //文本域
-    private JTextArea jta;
-    //滚动条
-    private JScrollPane jsp;
-    //面板
-    private JPanel jp;
-    //文本框
-    private JTextField jtf;
-    //按钮
-    private JButton jb;
-
-    //输出流
-    private BufferedWriter bw = null;
-    //服务端的端口号
-    private static int serverPort;
-    //使用 Static 静态代码块读取外部配置文件。
-    //特点1:在类加载的时候自动执行
-    //特点2:一个类只会被加载一次,因为静态代码块在程序中仅会被执行一次。
-    static {
-        Properties prop = new Properties();
-        try {
-            //加载
-            prop.load(new FileReader("OneToOne.properties"));
-            //给属性赋值
-            serverPort = Integer.parseInt(prop.getProperty("serverPort"));
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    //构造方法
-    public ServerChatMain() {
-        //初始化组件
-        //文本域
-        jta = new JTextArea();
-        //设置文本域不可编辑
-        jta.setEditable(false);
-        //滚动条  注意:需要将文本域添加到滚动条中,实现滚动效果。
-        jsp = new JScrollPane(jta);
-        //面板
-        jp = new JPanel();
-        //文本框  需要给长度
-        jtf= new JTextField(10);
-        //按钮  需要写按钮功能
-        jb = new JButton("发送");
-        //注意:需要将文本框和按钮添加到面板中
-        jp.add(jtf);
-        jp.add(jb);
-
-        //注意:需要将滚动条与面板添加到窗体中,并设置布局。
-        this.add(jsp, BorderLayout.CENTER);
-        this.add(jp,BorderLayout.SOUTH);
-
-        //注意:需要设置 “ 标题,大小,位置,关闭,是否可见 ”
-        this.setTitle("OneToOne聊天 服务端");
-        this.setSize(500,500);
-        this.setLocation(400,300);
-        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-        this.setVisible(true);
-
-        /*********************** TCP 服务端 start ***********************/
-        //给发送按钮绑定一个监听点击事件
-        jb.addActionListener(this);
-        //给文本框绑定键盘点击事件
-        jtf.addKeyListener(this);
-        try{
-            //1.创建一个服务端的套接字
-            ServerSocket serverSocket = new ServerSocket(serverPort);
-
-            //2.等待客户端的连接
-            Socket socket = serverSocket.accept();
-
-            //3.获取 Socket 通道的输入流(输入流是实现读取数据的,一行一行地取)BufferedReader -> readLine();
-            //InputStream in = socket.getInputStream();
-            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
-
-            //4.获取 Socket 通道的输出流(输出流实现写出数据,也是写一行换一行,刷新)BufferedWriter -> newLine();
-            //问题:什么时候需要写出数据??? 当用户点击 “ 发送 ” 按钮的时候才需要写出数据。
-            bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
-
-            //循环读取数据并拼接到文本域中
-            String line = null;
-            while ((line = br.readLine()) != null){
-                //将读取的数据拼接到文本域中显示
-                jta.append(line + System.lineSeparator());  //换行
-            }
-            //5.关闭 severSocket 通道
-            serverSocket.close();
-
-        }catch (IOException e){
-            e.printStackTrace();
-        }
-
-
-        /*********************** TCP 服务端 end  ***********************/
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent e) {
-        //System.out.println("发送按钮被点击了。。。");
-        sendDataToSocket();
-    }
-
-    //行为
-
-    @Override
-    public void keyPressed(KeyEvent e) {
-    //回车键
-        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
-            System.out.println(e);
-            //发送数据到 socket 通道中
-            sendDataToSocket();
-        }
-    }
-
-    //定义一个方法,实现将数据发送到 socket 通道中
-    private void sendDataToSocket(){
-        //1.获取文本框中发送的内容
-        String text = jtf.getText();
-        //2.拼接需要发送的数据内容
-        text = "服务端对客户端说:" + text ;
-        //3.发送之前自己显示
-        jta.append(text + System.lineSeparator());
-        try {
-            //4.发送
-            bw.write(text);
-            bw.newLine();
-            bw.flush();
-            //5.清空文本框内容
-            jtf.setText("");
-        } catch (IOException ex) {
-            ex.printStackTrace();
-        }
-    }
-
-    @Override
-    public void keyTyped(KeyEvent e) {
-    }
-
-    @Override
-    public void keyReleased(KeyEvent e) {
-    }
-
-}
-

+ 42 - 0
src/Sqlconn.java

@@ -0,0 +1,42 @@
+import java.sql.*;
+
+public class Sqlconn {
+    private boolean loginFlag;
+
+    public Sqlconn() {
+    }
+
+
+    public boolean login(String id,String passwd) throws ClassNotFoundException, SQLException {
+        String user = null;
+        Class.forName("com.mysql.cj.jdbc.Driver");
+
+        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?serverTimezone=UTC","root","root");
+
+        Statement stmt = conn.createStatement();
+        String sql;
+        sql = "select id from users where id='"+id+"' and password='"+passwd+"'";
+        
+        ResultSet rs = stmt.executeQuery(sql);
+        if(rs.next()){
+            user=rs.getString("id");
+        }
+        System.out.println(user);
+        return user!= null;
+
+    }
+    public boolean signup(String id,String passwd) throws ClassNotFoundException, SQLException {
+        Class.forName("com.mysql.cj.jdbc.Driver");
+
+        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?serverTimezone=UTC","root","root");
+
+
+        Statement stmt = conn.createStatement();
+        String sql;
+        sql = "insert into users values('"+id+"','"+passwd+"')";
+        int rs=stmt.executeUpdate(sql);
+
+        return rs!=0;
+
+    }
+}

+ 3 - 0
src/startClient.bat

@@ -0,0 +1,3 @@
+javac LoginFrame.java -encoding UTF-8
+java LoginFrame
+del *.class

+ 1 - 0
OneToOne.iml → talktalk.iml

@@ -7,5 +7,6 @@
     </content>
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="lib" level="project" />
   </component>
 </module>

+ 1 - 0
users.sql

@@ -0,0 +1 @@
+create table users(id varchar(20) not null ,password varchar(20) not null,PRIMARY KEY(id));