├── ChatClient ├── ChatClient.pro ├── ChatClient.pro.user ├── Makefile ├── chatLog.txt ├── chatconnection.cpp ├── chatconnection.h ├── chatdialog.cpp ├── chatdialog.h ├── chatserver.cpp ├── chatserver.h ├── debug.log ├── header.h ├── images │ ├── chatroom.ico │ └── icon.rc ├── logindialog.cpp ├── logindialog.h ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── peerinfo.cpp ├── peerinfo.h ├── registerconnection.cpp └── registerconnection.h ├── LICENSE ├── Material ├── P2P聊天软件设计文档.pdf ├── chat_dialog.jpg ├── chat_dialog2.jpg ├── client_gui.jpg ├── client_gui2.jpg ├── register_gui.jpg └── register_server_gui.jpg ├── README.md └── RegisterServer ├── Makefile ├── RegisterServer.pro ├── RegisterServer.pro.user ├── debug.log ├── header.h ├── images ├── icon.rc └── server.ico ├── main.cpp ├── peerinfo.cpp ├── peerinfo.h ├── registerLog.txt ├── registerconnection.cpp ├── registerconnection.h ├── registerserver.cpp ├── registerserver.h ├── window.cpp └── window.h /ChatClient/ChatClient.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2015-10-13T22:07:38 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui network sql 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = ChatClient 12 | TEMPLATE = app 13 | 14 | 15 | SOURCES += main.cpp\ 16 | mainwindow.cpp \ 17 | chatconnection.cpp \ 18 | chatdialog.cpp \ 19 | chatserver.cpp \ 20 | logindialog.cpp \ 21 | registerconnection.cpp \ 22 | peerinfo.cpp 23 | 24 | HEADERS += mainwindow.h \ 25 | chatconnection.h \ 26 | chatdialog.h \ 27 | chatserver.h \ 28 | header.h \ 29 | logindialog.h \ 30 | registerconnection.h \ 31 | peerinfo.h 32 | 33 | RC_FILE = images/icon.rc 34 | 35 | OTHER_FILES += \ 36 | images/icon.rc \ 37 | images/chatroom.ico 38 | -------------------------------------------------------------------------------- /ChatClient/ChatClient.pro.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | EnvironmentId 7 | {1f2d4bf0-dd7c-4612-97c0-0e08f39cb8c2} 8 | 9 | 10 | ProjectExplorer.Project.ActiveTarget 11 | 0 12 | 13 | 14 | ProjectExplorer.Project.EditorSettings 15 | 16 | true 17 | false 18 | true 19 | 20 | Cpp 21 | 22 | CppGlobal 23 | 24 | 25 | 26 | QmlJS 27 | 28 | QmlJSGlobal 29 | 30 | 31 | 2 32 | UTF-8 33 | false 34 | 4 35 | false 36 | 80 37 | true 38 | true 39 | 1 40 | true 41 | false 42 | 0 43 | true 44 | 0 45 | 8 46 | true 47 | 1 48 | true 49 | true 50 | true 51 | false 52 | 53 | 54 | 55 | ProjectExplorer.Project.PluginSettings 56 | 57 | 58 | 59 | ProjectExplorer.Project.Target.0 60 | 61 | Desktop Qt 5.6.0 MinGW 32bit 62 | Desktop Qt 5.6.0 MinGW 32bit 63 | qt.56.win32_mingw49_kit 64 | 0 65 | 0 66 | 0 67 | 68 | C:/Users/Adoryn/P2PChatRoom/ChatClient 69 | 70 | 71 | true 72 | qmake 73 | 74 | QtProjectManager.QMakeBuildStep 75 | true 76 | 77 | false 78 | false 79 | false 80 | 81 | 82 | true 83 | Make 84 | 85 | Qt4ProjectManager.MakeStep 86 | 87 | false 88 | 89 | 90 | 91 | 2 92 | 构建 93 | 94 | ProjectExplorer.BuildSteps.Build 95 | 96 | 97 | 98 | true 99 | Make 100 | 101 | Qt4ProjectManager.MakeStep 102 | 103 | true 104 | clean 105 | 106 | 107 | 1 108 | 清理 109 | 110 | ProjectExplorer.BuildSteps.Clean 111 | 112 | 2 113 | false 114 | 115 | Debug 116 | 117 | Qt4ProjectManager.Qt4BuildConfiguration 118 | 2 119 | true 120 | 121 | 122 | D:/CoreShare/Work/研究生作业/QtProjects/HomeWork/P2PChatRoom/build-ChatClient-Desktop_Qt_5_6_0_MinGW_32bit-Release 123 | 124 | 125 | true 126 | qmake 127 | 128 | QtProjectManager.QMakeBuildStep 129 | false 130 | 131 | false 132 | false 133 | false 134 | 135 | 136 | true 137 | Make 138 | 139 | Qt4ProjectManager.MakeStep 140 | 141 | false 142 | 143 | 144 | 145 | 2 146 | 构建 147 | 148 | ProjectExplorer.BuildSteps.Build 149 | 150 | 151 | 152 | true 153 | Make 154 | 155 | Qt4ProjectManager.MakeStep 156 | 157 | true 158 | clean 159 | 160 | 161 | 1 162 | 清理 163 | 164 | ProjectExplorer.BuildSteps.Clean 165 | 166 | 2 167 | false 168 | 169 | Release 170 | 171 | Qt4ProjectManager.Qt4BuildConfiguration 172 | 0 173 | true 174 | 175 | 176 | D:/CoreShare/Work/研究生作业/QtProjects/HomeWork/P2PChatRoom/build-ChatClient-Desktop_Qt_5_6_0_MinGW_32bit-Profile 177 | 178 | 179 | true 180 | qmake 181 | 182 | QtProjectManager.QMakeBuildStep 183 | true 184 | 185 | false 186 | true 187 | false 188 | 189 | 190 | true 191 | Make 192 | 193 | Qt4ProjectManager.MakeStep 194 | 195 | false 196 | 197 | 198 | 199 | 2 200 | 构建 201 | 202 | ProjectExplorer.BuildSteps.Build 203 | 204 | 205 | 206 | true 207 | Make 208 | 209 | Qt4ProjectManager.MakeStep 210 | 211 | true 212 | clean 213 | 214 | 215 | 1 216 | 清理 217 | 218 | ProjectExplorer.BuildSteps.Clean 219 | 220 | 2 221 | false 222 | 223 | Profile 224 | 225 | Qt4ProjectManager.Qt4BuildConfiguration 226 | 0 227 | true 228 | 229 | 3 230 | 231 | 232 | 0 233 | 部署 234 | 235 | ProjectExplorer.BuildSteps.Deploy 236 | 237 | 1 238 | 在本地部署 239 | 240 | ProjectExplorer.DefaultDeployConfiguration 241 | 242 | 1 243 | 244 | 245 | false 246 | 1000 247 | 248 | true 249 | 250 | false 251 | false 252 | false 253 | false 254 | true 255 | 0.01 256 | 10 257 | true 258 | 1 259 | 25 260 | 261 | 1 262 | true 263 | false 264 | true 265 | valgrind 266 | 267 | 0 268 | 1 269 | 2 270 | 3 271 | 4 272 | 5 273 | 6 274 | 7 275 | 8 276 | 9 277 | 10 278 | 11 279 | 12 280 | 13 281 | 14 282 | 283 | 2 284 | 285 | ChatClient 286 | ChatClient2 287 | Qt4ProjectManager.Qt4RunConfiguration:C:/Users/Adoryn/P2PChatRoom/ChatClient/ChatClient.pro 288 | true 289 | 290 | ChatClient.pro 291 | false 292 | false 293 | 294 | 3768 295 | false 296 | true 297 | false 298 | false 299 | true 300 | 301 | 1 302 | 303 | 304 | 305 | ProjectExplorer.Project.TargetCount 306 | 1 307 | 308 | 309 | ProjectExplorer.Project.Updater.FileVersion 310 | 18 311 | 312 | 313 | Version 314 | 18 315 | 316 | 317 | -------------------------------------------------------------------------------- /ChatClient/Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # Makefile for building: ChatClient 3 | # Generated by qmake (3.0) (Qt 5.6.0) 4 | # Project: ChatClient.pro 5 | # Template: app 6 | # Command: C:\Qt\Qt5.6.0\5.6\mingw49_32\bin\qmake.exe -spec win32-g++ "CONFIG+=debug" "CONFIG+=qml_debug" -o Makefile ChatClient.pro 7 | ############################################################################# 8 | 9 | MAKEFILE = Makefile 10 | 11 | first: debug 12 | install: debug-install 13 | uninstall: debug-uninstall 14 | QMAKE = C:\Qt\Qt5.6.0\5.6\mingw49_32\bin\qmake.exe 15 | DEL_FILE = del 16 | CHK_DIR_EXISTS= if not exist 17 | MKDIR = mkdir 18 | COPY = copy /y 19 | COPY_FILE = copy /y 20 | COPY_DIR = xcopy /s /q /y /i 21 | INSTALL_FILE = copy /y 22 | INSTALL_PROGRAM = copy /y 23 | INSTALL_DIR = xcopy /s /q /y /i 24 | DEL_FILE = del 25 | SYMLINK = $(QMAKE) -install ln -f -s 26 | DEL_DIR = rmdir 27 | MOVE = move 28 | SUBTARGETS = \ 29 | debug \ 30 | release 31 | 32 | 33 | debug: FORCE 34 | $(MAKE) -f $(MAKEFILE).Debug 35 | debug-make_first: FORCE 36 | $(MAKE) -f $(MAKEFILE).Debug 37 | debug-all: FORCE 38 | $(MAKE) -f $(MAKEFILE).Debug all 39 | debug-clean: FORCE 40 | $(MAKE) -f $(MAKEFILE).Debug clean 41 | debug-distclean: FORCE 42 | $(MAKE) -f $(MAKEFILE).Debug distclean 43 | debug-install: FORCE 44 | $(MAKE) -f $(MAKEFILE).Debug install 45 | debug-uninstall: FORCE 46 | $(MAKE) -f $(MAKEFILE).Debug uninstall 47 | release: FORCE 48 | $(MAKE) -f $(MAKEFILE).Release 49 | release-make_first: FORCE 50 | $(MAKE) -f $(MAKEFILE).Release 51 | release-all: FORCE 52 | $(MAKE) -f $(MAKEFILE).Release all 53 | release-clean: FORCE 54 | $(MAKE) -f $(MAKEFILE).Release clean 55 | release-distclean: FORCE 56 | $(MAKE) -f $(MAKEFILE).Release distclean 57 | release-install: FORCE 58 | $(MAKE) -f $(MAKEFILE).Release install 59 | release-uninstall: FORCE 60 | $(MAKE) -f $(MAKEFILE).Release uninstall 61 | 62 | Makefile: ChatClient.pro ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/win32-g++/qmake.conf ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/spec_pre.prf \ 63 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/qdevice.pri \ 64 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/device_config.prf \ 65 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/common/angle.conf \ 66 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/qconfig.pri \ 67 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dcore.pri \ 68 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dcore_private.pri \ 69 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dinput.pri \ 70 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dinput_private.pri \ 71 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dlogic.pri \ 72 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dlogic_private.pri \ 73 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquick.pri \ 74 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquick_private.pri \ 75 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquickinput.pri \ 76 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquickinput_private.pri \ 77 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquickrender.pri \ 78 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquickrender_private.pri \ 79 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3drender.pri \ 80 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3drender_private.pri \ 81 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axbase.pri \ 82 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axbase_private.pri \ 83 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axcontainer.pri \ 84 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axcontainer_private.pri \ 85 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axserver.pri \ 86 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axserver_private.pri \ 87 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_bluetooth.pri \ 88 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_bluetooth_private.pri \ 89 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_bootstrap_private.pri \ 90 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_clucene_private.pri \ 91 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_concurrent.pri \ 92 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_concurrent_private.pri \ 93 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_core.pri \ 94 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_core_private.pri \ 95 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_dbus.pri \ 96 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_dbus_private.pri \ 97 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_designer.pri \ 98 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_designer_private.pri \ 99 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_designercomponents_private.pri \ 100 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_gui.pri \ 101 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_gui_private.pri \ 102 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_help.pri \ 103 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_help_private.pri \ 104 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_labscontrols_private.pri \ 105 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_labstemplates_private.pri \ 106 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_location.pri \ 107 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_location_private.pri \ 108 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_multimedia.pri \ 109 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_multimedia_private.pri \ 110 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_multimediawidgets.pri \ 111 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_multimediawidgets_private.pri \ 112 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_network.pri \ 113 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_network_private.pri \ 114 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_nfc.pri \ 115 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_nfc_private.pri \ 116 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_opengl.pri \ 117 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_opengl_private.pri \ 118 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_openglextensions.pri \ 119 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_openglextensions_private.pri \ 120 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_platformsupport_private.pri \ 121 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_positioning.pri \ 122 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_positioning_private.pri \ 123 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_printsupport.pri \ 124 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_printsupport_private.pri \ 125 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qml.pri \ 126 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qml_private.pri \ 127 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qmldevtools_private.pri \ 128 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qmltest.pri \ 129 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qmltest_private.pri \ 130 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qtmultimediaquicktools_private.pri \ 131 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quick.pri \ 132 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quick_private.pri \ 133 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quickparticles_private.pri \ 134 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quickwidgets.pri \ 135 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quickwidgets_private.pri \ 136 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_script.pri \ 137 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_script_private.pri \ 138 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_scripttools.pri \ 139 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_scripttools_private.pri \ 140 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_sensors.pri \ 141 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_sensors_private.pri \ 142 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_serialbus.pri \ 143 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_serialbus_private.pri \ 144 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_serialport.pri \ 145 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_serialport_private.pri \ 146 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_sql.pri \ 147 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_sql_private.pri \ 148 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_svg.pri \ 149 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_svg_private.pri \ 150 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_testlib.pri \ 151 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_testlib_private.pri \ 152 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_uiplugin.pri \ 153 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_uitools.pri \ 154 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_uitools_private.pri \ 155 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_webchannel.pri \ 156 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_webchannel_private.pri \ 157 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_websockets.pri \ 158 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_websockets_private.pri \ 159 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_widgets.pri \ 160 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_widgets_private.pri \ 161 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_winextras.pri \ 162 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_winextras_private.pri \ 163 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_xml.pri \ 164 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_xml_private.pri \ 165 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_xmlpatterns.pri \ 166 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_xmlpatterns_private.pri \ 167 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/qt_functions.prf \ 168 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/qt_config.prf \ 169 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/qt_config.prf \ 170 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/win32-g++/qmake.conf \ 171 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/spec_post.prf \ 172 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/exclusive_builds.prf \ 173 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/default_pre.prf \ 174 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/default_pre.prf \ 175 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/resolve_config.prf \ 176 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/exclusive_builds_post.prf \ 177 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/default_post.prf \ 178 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/qml_debug.prf \ 179 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/rtti.prf \ 180 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/precompile_header.prf \ 181 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/warn_on.prf \ 182 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/qt.prf \ 183 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/resources.prf \ 184 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/moc.prf \ 185 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/opengl.prf \ 186 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/uic.prf \ 187 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/windows.prf \ 188 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/testcase_targets.prf \ 189 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/exceptions.prf \ 190 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/yacc.prf \ 191 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/lex.prf \ 192 | ChatClient.pro \ 193 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/qtmaind.prl \ 194 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/Qt5Widgets.prl \ 195 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/Qt5Gui.prl \ 196 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/Qt5Network.prl \ 197 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/Qt5Sql.prl \ 198 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/Qt5Core.prl 199 | $(QMAKE) -spec win32-g++ "CONFIG+=debug" "CONFIG+=qml_debug" -o Makefile ChatClient.pro 200 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/spec_pre.prf: 201 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/qdevice.pri: 202 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/device_config.prf: 203 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/common/angle.conf: 204 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/qconfig.pri: 205 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dcore.pri: 206 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dcore_private.pri: 207 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dinput.pri: 208 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dinput_private.pri: 209 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dlogic.pri: 210 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dlogic_private.pri: 211 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquick.pri: 212 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquick_private.pri: 213 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquickinput.pri: 214 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquickinput_private.pri: 215 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquickrender.pri: 216 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquickrender_private.pri: 217 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3drender.pri: 218 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3drender_private.pri: 219 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axbase.pri: 220 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axbase_private.pri: 221 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axcontainer.pri: 222 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axcontainer_private.pri: 223 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axserver.pri: 224 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axserver_private.pri: 225 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_bluetooth.pri: 226 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_bluetooth_private.pri: 227 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_bootstrap_private.pri: 228 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_clucene_private.pri: 229 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_concurrent.pri: 230 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_concurrent_private.pri: 231 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_core.pri: 232 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_core_private.pri: 233 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_dbus.pri: 234 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_dbus_private.pri: 235 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_designer.pri: 236 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_designer_private.pri: 237 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_designercomponents_private.pri: 238 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_gui.pri: 239 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_gui_private.pri: 240 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_help.pri: 241 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_help_private.pri: 242 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_labscontrols_private.pri: 243 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_labstemplates_private.pri: 244 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_location.pri: 245 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_location_private.pri: 246 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_multimedia.pri: 247 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_multimedia_private.pri: 248 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_multimediawidgets.pri: 249 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_multimediawidgets_private.pri: 250 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_network.pri: 251 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_network_private.pri: 252 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_nfc.pri: 253 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_nfc_private.pri: 254 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_opengl.pri: 255 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_opengl_private.pri: 256 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_openglextensions.pri: 257 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_openglextensions_private.pri: 258 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_platformsupport_private.pri: 259 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_positioning.pri: 260 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_positioning_private.pri: 261 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_printsupport.pri: 262 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_printsupport_private.pri: 263 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qml.pri: 264 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qml_private.pri: 265 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qmldevtools_private.pri: 266 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qmltest.pri: 267 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qmltest_private.pri: 268 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qtmultimediaquicktools_private.pri: 269 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quick.pri: 270 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quick_private.pri: 271 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quickparticles_private.pri: 272 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quickwidgets.pri: 273 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quickwidgets_private.pri: 274 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_script.pri: 275 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_script_private.pri: 276 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_scripttools.pri: 277 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_scripttools_private.pri: 278 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_sensors.pri: 279 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_sensors_private.pri: 280 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_serialbus.pri: 281 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_serialbus_private.pri: 282 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_serialport.pri: 283 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_serialport_private.pri: 284 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_sql.pri: 285 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_sql_private.pri: 286 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_svg.pri: 287 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_svg_private.pri: 288 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_testlib.pri: 289 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_testlib_private.pri: 290 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_uiplugin.pri: 291 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_uitools.pri: 292 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_uitools_private.pri: 293 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_webchannel.pri: 294 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_webchannel_private.pri: 295 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_websockets.pri: 296 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_websockets_private.pri: 297 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_widgets.pri: 298 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_widgets_private.pri: 299 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_winextras.pri: 300 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_winextras_private.pri: 301 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_xml.pri: 302 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_xml_private.pri: 303 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_xmlpatterns.pri: 304 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_xmlpatterns_private.pri: 305 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/qt_functions.prf: 306 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/qt_config.prf: 307 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/qt_config.prf: 308 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/win32-g++/qmake.conf: 309 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/spec_post.prf: 310 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/exclusive_builds.prf: 311 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/default_pre.prf: 312 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/default_pre.prf: 313 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/resolve_config.prf: 314 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/exclusive_builds_post.prf: 315 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/default_post.prf: 316 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/qml_debug.prf: 317 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/rtti.prf: 318 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/precompile_header.prf: 319 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/warn_on.prf: 320 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/qt.prf: 321 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/resources.prf: 322 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/moc.prf: 323 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/opengl.prf: 324 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/uic.prf: 325 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/windows.prf: 326 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/testcase_targets.prf: 327 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/exceptions.prf: 328 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/yacc.prf: 329 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/lex.prf: 330 | ChatClient.pro: 331 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/qtmaind.prl: 332 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/Qt5Widgets.prl: 333 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/Qt5Gui.prl: 334 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/Qt5Network.prl: 335 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/Qt5Sql.prl: 336 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/Qt5Core.prl: 337 | qmake: FORCE 338 | @$(QMAKE) -spec win32-g++ "CONFIG+=debug" "CONFIG+=qml_debug" -o Makefile ChatClient.pro 339 | 340 | qmake_all: FORCE 341 | 342 | make_first: debug-make_first release-make_first FORCE 343 | all: debug-all release-all FORCE 344 | clean: debug-clean release-clean FORCE 345 | distclean: debug-distclean release-distclean FORCE 346 | -$(DEL_FILE) Makefile 347 | 348 | debug-mocclean: 349 | $(MAKE) -f $(MAKEFILE).Debug mocclean 350 | release-mocclean: 351 | $(MAKE) -f $(MAKEFILE).Release mocclean 352 | mocclean: debug-mocclean release-mocclean 353 | 354 | debug-mocables: 355 | $(MAKE) -f $(MAKEFILE).Debug mocables 356 | release-mocables: 357 | $(MAKE) -f $(MAKEFILE).Release mocables 358 | mocables: debug-mocables release-mocables 359 | 360 | check: first 361 | FORCE: 362 | 363 | $(MAKEFILE).Debug: Makefile 364 | $(MAKEFILE).Release: Makefile 365 | -------------------------------------------------------------------------------- /ChatClient/chatLog.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adomy/P2PChatRoom/7871062b5125fdda109ed8506e692e749c60e878/ChatClient/chatLog.txt -------------------------------------------------------------------------------- /ChatClient/chatconnection.cpp: -------------------------------------------------------------------------------- 1 | #include "chatconnection.h" 2 | 3 | static const int TransferTimeout = 30 * 1000; 4 | static const char SeparatorToken = ' '; 5 | 6 | // ChatConnection初始化和信号槽连接 7 | ChatConnection::ChatConnection(QObject *parent) : 8 | QTcpSocket(parent) 9 | { 10 | this->greetingMessage = QObject::tr("undefined"); 11 | this->userName = QObject::tr("unknown"); 12 | this->state = WaitingForGreeting; 13 | this->currentDataType = UNDEFINED; 14 | this->numBytesForCurrentDataType = -1; 15 | this->transferTimerId = 0; 16 | this->isGreetingMessageSent = false; 17 | 18 | connect(this, SIGNAL(readyRead()), this, SLOT(processReadyRead())); 19 | connect(this, SIGNAL(connected()), this, SLOT(sendGreetingMessage())); 20 | connect(this, SIGNAL(disconnected()), this, SLOT(handleDisconnected())); 21 | connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(handleSocketError(QAbstractSocket::SocketError))); 22 | 23 | } 24 | 25 | // 获取ChatConnection对端的名字 26 | QString ChatConnection::getPeerName() 27 | { 28 | return this->userName; 29 | } 30 | 31 | // 获取ChatConnection对端的IP地址 32 | QString ChatConnection::getPeerIP() 33 | { 34 | return this->ip.toString(); 35 | } 36 | 37 | // 获取ChatConnection对端的端口号 38 | int ChatConnection::getPeerPort() 39 | { 40 | return this->port; 41 | } 42 | 43 | void ChatConnection::handleSocketError(QAbstractSocket::SocketError error) 44 | { 45 | emit this->socketError(this, error); 46 | } 47 | 48 | void ChatConnection::handleDisconnected() 49 | { 50 | emit this->disconnectedChat(this); 51 | } 52 | 53 | // 设置greeting消息 54 | void ChatConnection::setGreetingMessage(QString greet) 55 | { 56 | this->greetingMessage = greet; 57 | } 58 | 59 | // 定时器事件处理,此事件主要处理接收超时的问题(超时则关闭连接) 60 | void ChatConnection::timerEvent(QTimerEvent *timerEvent) 61 | { 62 | if(timerEvent->timerId() == this->transferTimerId) 63 | { 64 | this->abort(); 65 | this->killTimer(transferTimerId); 66 | transferTimerId = 0; 67 | } 68 | } 69 | 70 | // 发送message消息 71 | bool ChatConnection::sendMessage(const QString message) 72 | { 73 | if(message.isEmpty()) 74 | return false; 75 | 76 | QByteArray msg = message.toUtf8(); 77 | QByteArray data = "MESSAGE " + QByteArray::number(msg.size()) + ' ' + msg; 78 | return this->write(data) == data.size(); 79 | } 80 | 81 | // 发送greeting消息 82 | void ChatConnection::sendGreetingMessage() 83 | { 84 | QByteArray greeting = this->greetingMessage.toUtf8(); 85 | QByteArray data = "GREETING " + QByteArray::number(greeting.size()) + ' ' + greeting; 86 | if( this->write(data) == data.size() ) 87 | isGreetingMessageSent = true; 88 | } 89 | 90 | // 读取数据到buffer中,主要用于解析消息类型和消息长度 91 | int ChatConnection::readDataIntoBuffer(int maxSize) 92 | { 93 | if(maxSize > MaxBufferSize) 94 | return 0; 95 | 96 | int numBytesBeforeRead = this->buffer.size(); 97 | 98 | if(numBytesBeforeRead == MaxBufferSize) 99 | { 100 | this->abort(); 101 | return 0; 102 | } 103 | 104 | while(bytesAvailable() > 0 && buffer.size() < maxSize) 105 | { 106 | buffer.append(this->read(1)); 107 | if(buffer.endsWith(SeparatorToken)) 108 | break; 109 | } 110 | 111 | return buffer.size() - numBytesBeforeRead; 112 | } 113 | 114 | // 获取当前消息的消息长度 115 | int ChatConnection::dataLengthForCurrentDataType() 116 | { 117 | if(this->bytesAvailable() <= 0 || readDataIntoBuffer(MaxBufferSize) <= 0 || !buffer.endsWith(SeparatorToken)) 118 | return 0; 119 | 120 | this->buffer.chop(1); 121 | int length = buffer.toInt(); 122 | this->buffer.clear(); 123 | return length; 124 | } 125 | 126 | // 解析消息的头部信息,包括消息类型和消息长度 127 | bool ChatConnection::readProtocolHeader() 128 | { 129 | if(this->transferTimerId != 0) 130 | { 131 | this->killTimer(this->transferTimerId); 132 | this->transferTimerId = 0; 133 | } 134 | 135 | if(this->readDataIntoBuffer() <= 0) 136 | { 137 | this->transferTimerId = this->startTimer(TransferTimeout); 138 | return false; 139 | } 140 | 141 | if(buffer == "MESSAGE ") 142 | this->currentDataType = MESSAGE; 143 | else if(buffer == "GREETING ") 144 | this->currentDataType = GREETING; 145 | else 146 | { 147 | this->currentDataType = UNDEFINED; 148 | this->abort(); 149 | return false; 150 | } 151 | 152 | buffer.clear(); 153 | this->numBytesForCurrentDataType = this->dataLengthForCurrentDataType(); 154 | return true; 155 | } 156 | 157 | bool ChatConnection::hasEnoughData() 158 | { 159 | if(this->transferTimerId) 160 | { 161 | this->killTimer(transferTimerId); 162 | transferTimerId = 0; 163 | } 164 | 165 | if (numBytesForCurrentDataType <= 0) 166 | numBytesForCurrentDataType = this->dataLengthForCurrentDataType(); 167 | 168 | if (bytesAvailable() < numBytesForCurrentDataType 169 | || numBytesForCurrentDataType <= 0) 170 | { 171 | this->transferTimerId = this->startTimer(TransferTimeout); 172 | return false; 173 | } 174 | 175 | return true; 176 | } 177 | 178 | // 处理socket接收消息的核心函数,根据连接状态进行不同的操作 179 | void ChatConnection::processReadyRead() 180 | { 181 | if(this->state == WaitingForGreeting) 182 | { 183 | if(!this->readProtocolHeader()) 184 | return; 185 | if(this->currentDataType != GREETING) 186 | { 187 | this->abort(); 188 | return; 189 | } 190 | this->state = ReadingGreeting; 191 | } 192 | 193 | if(this->state == ReadingGreeting) 194 | { 195 | if(!this->hasEnoughData()) 196 | return; 197 | 198 | this->buffer = read(this->numBytesForCurrentDataType); 199 | if(buffer.size() != this->numBytesForCurrentDataType) 200 | { 201 | this->abort(); 202 | return; 203 | } 204 | 205 | QString greeting = QString::fromUtf8(this->buffer); 206 | 207 | if(DEBUG) 208 | qDebug() << "Get greeting message: " << greeting; 209 | 210 | QStringList addrList = greeting.split(":"); 211 | this->userName = addrList.at(0); 212 | QString ipStr = addrList.at(1); 213 | QString portStr = addrList.at(2); 214 | this->ip = QHostAddress(ipStr); 215 | this->port = portStr.toInt(); 216 | 217 | this->currentDataType = UNDEFINED; 218 | this->numBytesForCurrentDataType = 0; 219 | this->buffer.clear(); 220 | 221 | if(!this->isValid()) 222 | { 223 | this->abort(); 224 | return; 225 | } 226 | 227 | if(!this->isGreetingMessageSent) 228 | this->sendGreetingMessage(); 229 | 230 | this->state = ReadyForUse; 231 | emit this->endGreeting(this); 232 | } 233 | 234 | do 235 | { 236 | if(this->currentDataType == UNDEFINED) 237 | { 238 | if(!readProtocolHeader()) 239 | return; 240 | } 241 | if(!this->hasEnoughData()) 242 | return; 243 | this->processData(); 244 | }while(this->bytesAvailable() > 0); 245 | } 246 | 247 | // 该函数用于解析接收到的消息的内容部分 248 | void ChatConnection::processData() 249 | { 250 | this->buffer = this->read(this->numBytesForCurrentDataType); 251 | if(buffer.size() != this->numBytesForCurrentDataType) 252 | { 253 | this->abort(); 254 | return; 255 | } 256 | 257 | switch (currentDataType) { 258 | case MESSAGE: 259 | emit newMessage(this->userName, QString::fromUtf8(buffer)); 260 | break; 261 | default: 262 | break; 263 | } 264 | 265 | this->currentDataType = UNDEFINED; 266 | this->numBytesForCurrentDataType = -1; 267 | this->buffer.clear(); 268 | } 269 | 270 | -------------------------------------------------------------------------------- /ChatClient/chatconnection.h: -------------------------------------------------------------------------------- 1 | /* 说明: 2 | * 对于整个ChatConnection来说,其主要功能是提供用于建立聊天连接和进行聊天交互的信息接收与发送过程 3 | * 有几个设计性说明: 4 | * (1) ChatConnectionState 标识当前连接的状态,分别为等待greeting、读取greeting和读取聊天信息 5 | * (2) DataType 标识接收信息的类型,主要有greeting信息和message信息以及未定义的信息(错误) 6 | * 对于其结构来说,主要分为下面几个方面: 7 | * 1. 我们设置Greeting信息用于最初的连接建立时的连通性检测 8 | * peerHost <--->Greeting<---> peerHost 9 | * 当连接建立成功之后(发送connected信号),便发送greeting消息;同时,连接建立成功之后,连接工作在等待greeting的状态 10 | * 2. 对于消息的传递,我们设置了"消息类型 消息长度 消息内容"的传输格式,通过空格键相隔离 11 | * 因此,当我们解析消息时,首先应该去解析消息类型,然后读取消息长度,最后根据消息长度读取消息的内容 12 | * 3. 另外,对于ChatConnection,我们通过peer端的userName去标识该连接 13 | */ 14 | 15 | #ifndef CHATCONNECTION_H 16 | #define CHATCONNECTION_H 17 | 18 | #include "header.h" 19 | #include 20 | 21 | class ChatConnection : public QTcpSocket 22 | { 23 | Q_OBJECT 24 | public: 25 | explicit ChatConnection(QObject *parent = 0); 26 | 27 | enum ChatConnectionState{ 28 | WaitingForGreeting, 29 | ReadingGreeting, 30 | ReadyForUse 31 | }; 32 | 33 | enum DataType{ 34 | MESSAGE, 35 | GREETING, 36 | UNDEFINED 37 | }; 38 | 39 | QString getPeerName(); 40 | QString getPeerIP(); 41 | int getPeerPort(); 42 | void setGreetingMessage(QString message); 43 | bool sendMessage(QString message); 44 | 45 | signals: 46 | void endGreeting(ChatConnection *); 47 | void newMessage(QString from, QString message); 48 | void disconnectedChat(ChatConnection *); 49 | void socketError(ChatConnection *, QAbstractSocket::SocketError); 50 | 51 | protected: 52 | void timerEvent(QTimerEvent *); 53 | 54 | private slots: 55 | void processReadyRead(); 56 | void sendGreetingMessage(); 57 | void handleDisconnected(); 58 | void handleSocketError(QAbstractSocket::SocketError); 59 | 60 | private: 61 | int readDataIntoBuffer(int maxSize = MaxBufferSize); 62 | int dataLengthForCurrentDataType(); 63 | bool readProtocolHeader(); 64 | bool hasEnoughData(); 65 | void processData(); 66 | 67 | QString userName; //通过远端的信息来标识该连接 68 | QHostAddress ip; 69 | int port; 70 | QString greetingMessage; 71 | QByteArray buffer; 72 | enum ChatConnectionState state; 73 | enum DataType currentDataType; 74 | int numBytesForCurrentDataType; 75 | int transferTimerId; 76 | bool isGreetingMessageSent; 77 | }; 78 | 79 | #endif // CHATCONNECTION_H 80 | -------------------------------------------------------------------------------- /ChatClient/chatdialog.cpp: -------------------------------------------------------------------------------- 1 | #include "chatdialog.h" 2 | 3 | ChatDialog::ChatDialog(QWidget *parent, QString username, QString peername, QString peeraddr, ChatConnection *connection) : 4 | QDialog(parent) 5 | { 6 | this->userName = username; 7 | this->chatSession = connection; 8 | 9 | if(DEBUG) 10 | qDebug() << "Peer addr string is: " << peeraddr; 11 | 12 | //this->iconLabel = new QLabel(QObject::tr("XXXXX\nXXXXX\nXXXXX"), this); 13 | //this->iconLabel->setAlignment(Qt::AlignCenter); 14 | this->peerName = new QLabel(this); 15 | this->peerAddress = new QLabel(this); 16 | this->logChat = new QTextEdit(); 17 | this->msgSend = new QLineEdit(); 18 | this->sendButton = new QPushButton(QObject::tr("Send"), this); 19 | this->msgSend->setFocusPolicy(Qt::StrongFocus); 20 | this->logChat->setFocusPolicy(Qt::NoFocus); 21 | this->logChat->setReadOnly(true); 22 | 23 | this->peerName->setText("Username: " + peername); 24 | this->peerAddress->setText("Address: " + peeraddr); 25 | this->setWindowTitle(peername + "@" + peeraddr); 26 | this->initLayout(); 27 | this->resize(QSize(480, 360)); 28 | 29 | connect(sendButton, SIGNAL(clicked()), this, SLOT(handleToSendMessage())); 30 | connect(msgSend, SIGNAL(returnPressed()), this, SLOT(handleToSendMessage())); 31 | 32 | connect(chatSession, SIGNAL(newMessage(QString, QString)), this, SLOT(handleReceivedMssage(QString, QString))); 33 | connect(chatSession, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(handleConnectionError(QAbstractSocket::SocketError))); 34 | connect(this, SIGNAL(rejected()), this, SLOT(handleRejected())); 35 | } 36 | 37 | ChatDialog::~ChatDialog() 38 | { 39 | 40 | } 41 | 42 | void ChatDialog::initLayout() 43 | { 44 | QVBoxLayout *infoLayout = new QVBoxLayout; 45 | infoLayout->addWidget(peerName); 46 | infoLayout->addWidget(peerAddress); 47 | 48 | /**************************************** 49 | QHBoxLayout *peerLayout = new QHBoxLayout; 50 | peerLayout->addWidget(iconLabel); 51 | peerLayout->addLayout(infoLayout); 52 | peerLayout->setStretch(0, 1); 53 | peerLayout->setStretch(1, 6); 54 | ****************************************/ 55 | 56 | QHBoxLayout *sendLayout = new QHBoxLayout; 57 | sendLayout->addWidget(msgSend); 58 | sendLayout->addWidget(sendButton); 59 | sendLayout->setStretch(0, 5); 60 | sendLayout->setStretch(1, 1); 61 | 62 | QVBoxLayout *dialogLayout = new QVBoxLayout; 63 | //dialogLayout->addLayout(peerLayout); 64 | dialogLayout->addLayout(infoLayout); 65 | dialogLayout->addWidget(logChat); 66 | dialogLayout->addLayout(sendLayout); 67 | dialogLayout->setStretch(0, 1); 68 | dialogLayout->setStretch(1, 8); 69 | dialogLayout->setStretch(2, 2); 70 | 71 | this->setLayout(dialogLayout); 72 | } 73 | 74 | void ChatDialog::handleReceivedMssage(QString from, QString message) 75 | { 76 | if (from.isEmpty() || message.isEmpty()) 77 | return; 78 | 79 | QDateTime time = QDateTime::currentDateTime(); 80 | QString timeString = time.toString("hh:mm:ss MM-dd"); 81 | QString infoString = from + "(" + timeString + "): "; 82 | QColor color = this->logChat->textColor(); 83 | this->logChat->setTextColor(Qt::blue); 84 | this->logChat->append(infoString); 85 | this->logChat->append(message + "\n"); 86 | this->logChat->setTextColor(color); 87 | QScrollBar *bar = logChat->verticalScrollBar(); 88 | bar->setValue(bar->maximum()); 89 | } 90 | 91 | void ChatDialog::readAndDisplayHistory(QList strList) 92 | { 93 | QColor color = this->logChat->textColor(); 94 | this->logChat->setTextColor(Qt::blue); 95 | foreach(QString s, strList) 96 | this->logChat->append(s); 97 | this->logChat->setTextColor(color); 98 | QScrollBar *bar = logChat->verticalScrollBar(); 99 | bar->setValue(bar->maximum()); 100 | } 101 | 102 | void ChatDialog::handleToSendMessage() 103 | { 104 | QString text = this->msgSend->text(); 105 | if (text.isEmpty()) 106 | return; 107 | 108 | QColor color = logChat->textColor(); 109 | if (text.startsWith(QChar('/'))) { 110 | this->logChat->setTextColor(Qt::black); 111 | this->logChat->append(tr("Unknown command: %1") 112 | .arg(text.left(text.indexOf(' ')))); 113 | } 114 | else 115 | { 116 | if(!chatSession->sendMessage(text)) 117 | { 118 | this->logChat->setTextColor(Qt::red); 119 | this->logChat->append("Transfer Error: cannot send message: " + text); 120 | this->msgSend->clear(); 121 | this->logChat->setTextColor(color); 122 | QScrollBar *bar = logChat->verticalScrollBar(); 123 | bar->setValue(bar->maximum()); 124 | 125 | if(DEBUG) 126 | qDebug() << "Error send message."; 127 | return; 128 | } 129 | 130 | QDateTime time = QDateTime::currentDateTime(); 131 | QString timeString = time.toString("hh:mm:ss MM-dd"); 132 | QString infoString = this->userName + "(" + timeString + ") : "; 133 | 134 | QColor color = this->logChat->textColor(); 135 | this->logChat->setTextColor(Qt::black); 136 | this->logChat->append(infoString); 137 | this->logChat->append(text + "\n"); 138 | this->logChat->setTextColor(color); 139 | 140 | QScrollBar *bar = logChat->verticalScrollBar(); 141 | bar->setValue(bar->maximum()); 142 | } 143 | 144 | this->msgSend->clear(); 145 | this->logChat->setTextColor(color); 146 | 147 | if(DEBUG) 148 | qDebug() << "Send Message Success" << endl; 149 | } 150 | 151 | void ChatDialog::handleConnectionError(QAbstractSocket::SocketError error) 152 | { 153 | this->chatSession->close(); 154 | QString errorString; 155 | switch(error) 156 | { 157 | case QAbstractSocket::ConnectionRefusedError: 158 | errorString = "Connection refused!"; 159 | break; 160 | case QAbstractSocket::RemoteHostClosedError: 161 | errorString = "Remote host closed."; 162 | break; 163 | case QAbstractSocket::HostNotFoundError: 164 | errorString = "Host not found!"; 165 | break; 166 | case QAbstractSocket::NetworkError: 167 | errorString = "Network error!"; 168 | break; 169 | case QAbstractSocket::AddressInUseError: 170 | errorString = "Address already in use!"; 171 | break; 172 | case QAbstractSocket::UnknownSocketError: 173 | default: 174 | errorString = "Unknown socket error!"; 175 | break; 176 | } 177 | QColor color = this->logChat->textColor(); 178 | this->logChat->setTextColor(Qt::red); 179 | this->logChat->append("Connection Error:" + errorString); 180 | this->logChat->setTextColor(color); 181 | } 182 | 183 | void ChatDialog::handleRejected() 184 | { 185 | emit this->dialogExit(this->chatSession); 186 | this->chatSession->close(); 187 | } 188 | -------------------------------------------------------------------------------- /ChatClient/chatdialog.h: -------------------------------------------------------------------------------- 1 | #ifndef CHATDIALOG_H 2 | #define CHATDIALOG_H 3 | 4 | #include "header.h" 5 | #include "chatconnection.h" 6 | #include 7 | 8 | class ChatDialog : public QDialog 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | explicit ChatDialog(QWidget *parent = 0, QString username = "localhost", QString peername = "unknown", QString peeraddr = "null", ChatConnection *connection = NULL); 14 | ~ChatDialog(); 15 | 16 | void readAndDisplayHistory(QList); 17 | 18 | signals: 19 | void dialogExit(ChatConnection *); 20 | 21 | public slots: 22 | void handleReceivedMssage(QString from, QString message); 23 | void handleToSendMessage(); 24 | void handleConnectionError(QAbstractSocket::SocketError); 25 | void handleRejected(); 26 | 27 | private: 28 | // private functions 29 | void initLayout(); 30 | 31 | /*Qt Widgets*/ 32 | //QLabel *iconLabel; 33 | QLabel *peerName; 34 | QLabel *peerAddress; 35 | QTextEdit *logChat; 36 | QLineEdit *msgSend; 37 | QPushButton *sendButton; 38 | 39 | // Connection part 40 | QString userName; 41 | ChatConnection *chatSession; 42 | }; 43 | 44 | #endif // CHATDIALOG_H 45 | -------------------------------------------------------------------------------- /ChatClient/chatserver.cpp: -------------------------------------------------------------------------------- 1 | #include "chatserver.h" 2 | 3 | ChatServer::ChatServer(QObject *parent) : 4 | QTcpServer(parent) 5 | { 6 | this->myIp = QHostAddress::AnyIPv4; 7 | this->myPort = 9001; 8 | } 9 | 10 | void ChatServer::setChatServerInfo(QHostAddress &ip, int &port) 11 | { 12 | this->myIp = ip; 13 | this->myPort = port; 14 | } 15 | 16 | bool ChatServer::startServer() 17 | { 18 | return this->listen(this->myIp, this->myPort); 19 | } 20 | 21 | void ChatServer::incomingConnection(qintptr socketDescriptor) 22 | { 23 | ChatConnection *connection = new ChatConnection(this); 24 | connection->setSocketDescriptor(socketDescriptor); 25 | emit newChatConnection(connection); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /ChatClient/chatserver.h: -------------------------------------------------------------------------------- 1 | #ifndef CHATSERVER_H 2 | #define CHATSERVER_H 3 | 4 | #include "header.h" 5 | #include "chatconnection.h" 6 | #include 7 | 8 | class ChatServer : public QTcpServer 9 | { 10 | Q_OBJECT 11 | public: 12 | explicit ChatServer(QObject *parent = 0); 13 | 14 | void setChatServerInfo(QHostAddress &ip, int &port); 15 | bool startServer(); 16 | 17 | signals: 18 | void newChatConnection(ChatConnection *connection); 19 | 20 | protected: 21 | void incomingConnection(qintptr socketDescriptor); 22 | 23 | private: 24 | QHostAddress myIp; 25 | int myPort; 26 | }; 27 | 28 | #endif // CHATSERVER_H 29 | -------------------------------------------------------------------------------- /ChatClient/debug.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adomy/P2PChatRoom/7871062b5125fdda109ed8506e692e749c60e878/ChatClient/debug.log -------------------------------------------------------------------------------- /ChatClient/header.h: -------------------------------------------------------------------------------- 1 | #ifndef HEADER_H 2 | #define HEADER_H 3 | 4 | // General Methods 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | // Widgets 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | // Notification Methods 39 | #include 40 | 41 | // Qt Network 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | 49 | // Related to Qt Mysql operations 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | // Related to Json File operations 56 | #include 57 | #include 58 | #include 59 | #include 60 | 61 | #define MaxBufferSize 1024000 62 | #define DEBUG 0 63 | 64 | #endif // HEADER_H 65 | -------------------------------------------------------------------------------- /ChatClient/images/chatroom.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adomy/P2PChatRoom/7871062b5125fdda109ed8506e692e749c60e878/ChatClient/images/chatroom.ico -------------------------------------------------------------------------------- /ChatClient/images/icon.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "chatroom.ico" -------------------------------------------------------------------------------- /ChatClient/logindialog.cpp: -------------------------------------------------------------------------------- 1 | #include "logindialog.h" 2 | 3 | LoginDialog::LoginDialog(QWidget *parent) 4 | : QDialog(parent) 5 | { 6 | // Initialization Parts 7 | this->loginLogo = new QLabel(QObject::tr("Register client"), this); 8 | this->loginLogo->setAlignment(Qt::AlignCenter); 9 | 10 | this->loginUsername = new QLabel(QObject::tr("Username:"), this); 11 | this->editUsername = new QLineEdit(this); 12 | this->localIPAddress = new QLabel(QObject::tr("Local IP:"), this); 13 | this->localIPAddressBox = new QComboBox(this); 14 | this->localPort = new QLabel(QObject::tr("Local Port:"), this); 15 | this->localPortBox = new QSpinBox(this); 16 | this->registerIpLabel = new QLabel(QObject::tr("Server IP:"), this); 17 | this->registerIpEdit = new QLineEdit(this); 18 | this->registerPortLabel = new QLabel(QObject::tr("Server Port"), this); 19 | this->registerPortBox = new QSpinBox(this); 20 | this->registerIpLabel->setBuddy(this->registerIpEdit); 21 | this->registerPortLabel->setBuddy(this->registerPortBox); 22 | this->loginUsername->setBuddy(this->editUsername); 23 | this->localIPAddress->setBuddy(this->localIPAddressBox); 24 | this->localPort->setBuddy(this->localPortBox); 25 | 26 | this->networkInterfacesCombo(); 27 | this->localPortBox->setRange(1024, 65535); 28 | this->localPortBox->setValue(9001); 29 | this->registerPortBox->setRange(1024, 65535); 30 | this->registerPortBox->setValue(10001); 31 | this->editUsername->setText("unknown"); 32 | this->registerIpEdit->setText("192.168.1.106"); 33 | 34 | // Button Settings 35 | this->doneButton = new QPushButton(QObject::tr("Register"), this); 36 | this->cancelButton = new QPushButton(QObject::tr("Cancel"), this); 37 | this->doneButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 38 | this->cancelButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 39 | 40 | this->initLayout(); 41 | this->resize(QSize(300, 220)); 42 | this->setMinimumSize(QSize(250, 180)); 43 | this->setWindowTitle(QObject::tr("Client Register")); 44 | 45 | connect(doneButton, SIGNAL(clicked()), this, SLOT(on_doneButton_clicked())); 46 | connect(cancelButton, SIGNAL(clicked()), this, SLOT(on_cancelButton_clicked())); 47 | } 48 | 49 | LoginDialog::~LoginDialog() 50 | { 51 | } 52 | 53 | void LoginDialog::networkInterfacesCombo() 54 | { 55 | QList list = QNetworkInterface::allAddresses(); 56 | foreach( QHostAddress address, list ) 57 | { 58 | if(address.protocol() == QAbstractSocket::IPv4Protocol) 59 | this->localIPAddressBox->addItem(address.toString()); 60 | } 61 | } 62 | 63 | void LoginDialog::initLayout() 64 | { 65 | // Layout Manager 66 | QHBoxLayout *userLayout = new QHBoxLayout; 67 | userLayout->addWidget(this->loginUsername); 68 | userLayout->addWidget(this->editUsername); 69 | userLayout->setStretch(0, 1); 70 | userLayout->setStretch(1, 3); 71 | 72 | QHBoxLayout *ipLayout = new QHBoxLayout; 73 | ipLayout->addWidget(this->localIPAddress); 74 | ipLayout->addWidget(this->localIPAddressBox); 75 | ipLayout->setStretch(0, 1); 76 | ipLayout->setStretch(1, 3); 77 | 78 | QHBoxLayout *portLayout = new QHBoxLayout; 79 | portLayout->addWidget(this->localPort); 80 | portLayout->addWidget(this->localPortBox); 81 | portLayout->setStretch(0, 1); 82 | portLayout->setStretch(1, 3); 83 | 84 | QHBoxLayout *ripLayout = new QHBoxLayout; 85 | ripLayout->addWidget(this->registerIpLabel); 86 | ripLayout->addWidget(this->registerIpEdit); 87 | ripLayout->setStretch(0, 1); 88 | ripLayout->setStretch(1, 3); 89 | 90 | QHBoxLayout *rportLayout = new QHBoxLayout; 91 | rportLayout->addWidget(this->registerPortLabel); 92 | rportLayout->addWidget(this->registerPortBox); 93 | rportLayout->setStretch(0, 1); 94 | rportLayout->setStretch(1, 3); 95 | 96 | QHBoxLayout *buttonLayout = new QHBoxLayout; 97 | buttonLayout->addStretch(); 98 | buttonLayout->addWidget(this->doneButton); 99 | buttonLayout->addStretch(); 100 | buttonLayout->addWidget(this->cancelButton); 101 | buttonLayout->addStretch(); 102 | 103 | QVBoxLayout *mainLayout = new QVBoxLayout; 104 | mainLayout->addWidget(this->loginLogo); 105 | mainLayout->addLayout(userLayout); 106 | mainLayout->addLayout(ipLayout); 107 | mainLayout->addLayout(portLayout); 108 | mainLayout->addLayout(ripLayout); 109 | mainLayout->addLayout(rportLayout); 110 | mainLayout->addStretch(); 111 | mainLayout->addLayout(buttonLayout); 112 | mainLayout->setStretch(0, 2); 113 | mainLayout->setStretch(1, 1); 114 | mainLayout->setStretch(2, 1); 115 | mainLayout->setStretch(3, 1); 116 | mainLayout->setStretch(4, 1); 117 | mainLayout->setStretch(5, 1); 118 | mainLayout->setStretch(6, 1); 119 | 120 | this->setLayout(mainLayout); 121 | } 122 | 123 | 124 | QString LoginDialog::getUsername() 125 | { 126 | QString username = this->editUsername->text(); 127 | if(username.isEmpty()) 128 | username = "unknown"; 129 | 130 | return username; 131 | } 132 | 133 | QString LoginDialog::getLocalServerIP() 134 | { 135 | QString ipAddress = this->localIPAddressBox->currentText(); 136 | if(ipAddress.isEmpty()) 137 | ipAddress = "localhost"; 138 | 139 | return ipAddress; 140 | } 141 | 142 | int LoginDialog::getLocalServerPort() 143 | { 144 | return this->localPortBox->value(); 145 | } 146 | 147 | QString LoginDialog::getRegisterServerIP() 148 | { 149 | QString serverIp = this->registerIpEdit->text(); 150 | if(serverIp.isEmpty()) 151 | serverIp = "192.168.1.106"; 152 | 153 | return serverIp; 154 | } 155 | 156 | int LoginDialog::getRegisterServerPort() 157 | { 158 | return this->registerPortBox->value(); 159 | } 160 | 161 | void LoginDialog::on_doneButton_clicked() 162 | { 163 | this->accept(); 164 | } 165 | 166 | void LoginDialog::on_cancelButton_clicked() 167 | { 168 | this->reject(); 169 | } 170 | -------------------------------------------------------------------------------- /ChatClient/logindialog.h: -------------------------------------------------------------------------------- 1 | #ifndef LOGINDIALOG_H 2 | #define LOGINDIALOG_H 3 | 4 | #include "header.h" 5 | #include 6 | 7 | 8 | class LoginDialog : public QDialog 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | LoginDialog(QWidget *parent = 0); 14 | ~LoginDialog(); 15 | 16 | QString getUsername(); 17 | QString getLocalServerIP(); 18 | int getLocalServerPort(); 19 | QString getRegisterServerIP(); 20 | int getRegisterServerPort(); 21 | 22 | signals: 23 | 24 | 25 | public slots: 26 | void on_doneButton_clicked(); 27 | void on_cancelButton_clicked(); 28 | 29 | private: 30 | // private functions 31 | void networkInterfacesCombo(); 32 | void initLayout(); 33 | 34 | // login information 35 | QLabel *loginLogo; 36 | QLabel *loginUsername; 37 | QLineEdit *editUsername; 38 | QLabel *localIPAddress; 39 | QComboBox *localIPAddressBox; 40 | QLabel *localPort; 41 | QSpinBox *localPortBox; 42 | QLabel *registerIpLabel; 43 | QLineEdit *registerIpEdit; 44 | QLabel *registerPortLabel; 45 | QSpinBox *registerPortBox; 46 | QPushButton *doneButton; 47 | QPushButton *cancelButton; 48 | 49 | }; 50 | 51 | #endif // LOGINDIALOG_H 52 | -------------------------------------------------------------------------------- /ChatClient/main.cpp: -------------------------------------------------------------------------------- 1 | #include "logindialog.h" 2 | #include "mainwindow.h" 3 | #include "chatdialog.h" 4 | #include 5 | 6 | void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg); 7 | void clearLogFile(); 8 | 9 | int main(int argc, char *argv[]) 10 | { 11 | clearLogFile(); 12 | qInstallMessageHandler(outputMessage); 13 | QApplication a(argc, argv); 14 | MainWindow w; 15 | w.show(); 16 | return a.exec(); 17 | } 18 | 19 | void clearLogFile() 20 | { 21 | QFile file("chatLog.txt"); 22 | file.open(QIODevice::WriteOnly | QIODevice::Append); 23 | file.resize(0); 24 | file.flush(); 25 | file.close(); 26 | } 27 | 28 | void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg) 29 | { 30 | static QMutex mutex; 31 | 32 | QString text; 33 | switch(type) 34 | { 35 | case QtDebugMsg: 36 | text = QString("Debug:"); 37 | break; 38 | 39 | case QtWarningMsg: 40 | text = QString("Warning:"); 41 | break; 42 | 43 | case QtCriticalMsg: 44 | text = QString("Critical:"); 45 | break; 46 | 47 | case QtFatalMsg: 48 | text = QString("Fatal:"); 49 | break; 50 | 51 | default: 52 | break; 53 | } 54 | 55 | QString context_info = QString("(%1:%2)").arg(QString(context.file)).arg(context.line); 56 | QString message = QString("%1 %2\r\n %3").arg(text).arg(context_info).arg(msg); 57 | 58 | mutex.lock(); 59 | 60 | QFile file("chatLog.txt"); 61 | file.open(QIODevice::WriteOnly | QIODevice::Append); 62 | QTextStream text_stream(&file); 63 | text_stream << message << "\r\n"; 64 | file.flush(); 65 | file.close(); 66 | 67 | mutex.unlock(); 68 | } 69 | -------------------------------------------------------------------------------- /ChatClient/mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | 3 | MainWindow::MainWindow(QWidget *parent) : 4 | QMainWindow(parent) 5 | { 6 | this->myName = new QLabel(QObject::tr("Username: none"), this); 7 | this->myAddress = new QLabel(QObject::tr("Address: client unregistered."), this); 8 | //this->myIcon = new QLabel(QObject::tr("XXXXX\nXXXXX\nXXXXX"), this); 9 | //this->myIcon->setAlignment(Qt::AlignCenter); 10 | this->infoLabel = new QLabel(QObject::tr("Active peer list:"), this); 11 | this->peerListWidget = new QListWidget(); 12 | this->chatButton = new QPushButton(QObject::tr("New Chat"), this); 13 | this->registerButton = new QPushButton(QObject::tr("Register"), this); 14 | this->checkButton = new QPushButton(QObject::tr("Recv Chat"), this); 15 | this->remoteServerLabel = new QLabel("Not set register server info."); 16 | this->server = new ChatServer(this); 17 | this->registConnection = new RegisterConnection(this); 18 | this->initLayout(); 19 | this->setWindowTitle(QObject::tr("Chat Room")); 20 | this->resize(QSize(340, 500)); 21 | this->setMinimumSize(QSize(280, 320)); 22 | 23 | connect(this->chatButton, SIGNAL(clicked()), this, SLOT(handleActiveConnection())); 24 | connect(this->registerButton, SIGNAL(clicked()), this, SLOT(handleRegisterAction())); 25 | connect(this->checkButton, SIGNAL(clicked()), this, SLOT(handleCheckDialog())); 26 | } 27 | 28 | MainWindow::~MainWindow() 29 | { 30 | this->server->close(); 31 | this->registConnection->close(); 32 | } 33 | 34 | void MainWindow::initLayout() 35 | { 36 | QVBoxLayout *myTextLayout = new QVBoxLayout; 37 | myTextLayout->addWidget(myName); 38 | myTextLayout->addWidget(myAddress); 39 | 40 | /****************************************** 41 | QHBoxLayout *myInfoLayout = new QHBoxLayout; 42 | myInfoLayout->addWidget(myIcon); 43 | myInfoLayout->addLayout(myTextLayout); 44 | myInfoLayout->setStretch(0, 1); 45 | myInfoLayout->setStretch(1, 5); 46 | *******************************************/ 47 | 48 | QHBoxLayout *chatLayout = new QHBoxLayout; 49 | chatLayout->addWidget(registerButton); 50 | chatLayout->addStretch(); 51 | chatLayout->addWidget(checkButton); 52 | chatLayout->addWidget(chatButton); 53 | 54 | QVBoxLayout *mainLayout = new QVBoxLayout; 55 | //mainLayout->addLayout(myInfoLayout); 56 | mainLayout->addLayout(myTextLayout); 57 | mainLayout->addWidget(infoLabel); 58 | mainLayout->addWidget(peerListWidget); 59 | mainLayout->addLayout(chatLayout); 60 | mainLayout->addWidget(remoteServerLabel); 61 | 62 | QWidget *widget = new QWidget(this); 63 | widget->setLayout(mainLayout); 64 | 65 | this->setCentralWidget(widget); 66 | } 67 | 68 | // 网络模块启动部分,包括启动本地的聊天服务器,以及连接至注册服务器 69 | void MainWindow::initNetwork() 70 | { 71 | // 启动ChatServer 72 | if(DEBUG) 73 | { 74 | qDebug() << "Local server ip address: " << this->localServerIP.toString(); 75 | qDebug() << "Local server port: " << this->localServerPort; 76 | } 77 | 78 | this->server->setChatServerInfo(this->localServerIP, this->localServerPort); 79 | if(this->server->startServer()) 80 | { 81 | QString address = this->localServerIP.toString() + ":" + QString::number(this->localServerPort); 82 | this->myName->setText("Username: " + this->userName); 83 | this->myAddress->setText("Address: " + address); 84 | 85 | QString remoteAddress = QString("Register Server Info: ") + this->remoteServerIP.toString() + ":" + QString::number(this->remoteServerPort); 86 | this->remoteServerLabel->setText(remoteAddress); 87 | 88 | this->registerButton->setEnabled(false); 89 | if(DEBUG) 90 | qDebug() << "Local chat server started."; 91 | } 92 | else 93 | { 94 | this->remoteServerLabel->setText("Cannot start local chat server."); 95 | this->registerButton->setEnabled(true); 96 | QMessageBox::warning(this, tr("Error"), tr("Cannot start local chat server!")); 97 | if(DEBUG) 98 | qDebug() << "Cannot start local chat server."; 99 | return; 100 | } 101 | connect(server, SIGNAL(newChatConnection(ChatConnection*)), this, SLOT(handlePassiveConnection(ChatConnection*))); 102 | 103 | // 连接至中心注册服务器 104 | if(DEBUG) 105 | qDebug() << "Connect to register server."; 106 | this->registConnection->setLocalServerInfo(this->userName, this->localServerIP, this->localServerPort); 107 | this->registConnection->connectToHost(this->remoteServerIP, this->remoteServerPort); 108 | if(DEBUG) 109 | qDebug() << "Connected to register server."; 110 | connect(registConnection, SIGNAL(newPeerList(QString&)), this, SLOT(handleNewPeerList(QString&))); 111 | connect(registConnection, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(handleRegisterError(QAbstractSocket::SocketError))); 112 | } 113 | 114 | void MainWindow::handleRegisterAction() 115 | { 116 | LoginDialog *ld = new LoginDialog(this); 117 | if (ld->exec() != QDialog::Accepted) 118 | { 119 | QMessageBox::warning(this, tr("Warning"), tr("Client Register Canceled!")); 120 | return; 121 | } 122 | 123 | this->userName = ld->getUsername(); 124 | this->localServerIP = ld->getLocalServerIP(); 125 | this->localServerPort = ld->getLocalServerPort(); 126 | this->remoteServerIP = ld->getRegisterServerIP(); 127 | this->remoteServerPort = ld->getRegisterServerPort(); 128 | 129 | if(DEBUG) 130 | { 131 | qDebug() << "Register client configuration done!"; 132 | qDebug() << "Local server name: " << this->userName; 133 | qDebug() << "Local server ip address: " << this->localServerIP; 134 | qDebug() << "Local server port: " << this->localServerPort; 135 | } 136 | 137 | this->initNetwork(); 138 | } 139 | 140 | void MainWindow::updateListWidget() 141 | { 142 | this->peerListWidget->clear(); 143 | for(int i = 0; i < this->peerList.size(); i++) 144 | { 145 | QString comment = ""; 146 | PeerInfo *pi = this->peerList.at(i); 147 | QString name = pi->getPeerName(); 148 | if(name == this->userName) 149 | comment = " ( local )"; 150 | if(this->tempMsgs.contains(name)) 151 | comment = " ( new message: " + QString::number(this->tempMsgs[name].size()) + " )"; 152 | QString itemString = pi->getPeerName() + "@" + pi->getPeerIP() + ":" + QString::number(pi->getPeerPort()) + comment; 153 | this->peerListWidget->addItem(new QListWidgetItem(itemString)); 154 | } 155 | } 156 | 157 | void MainWindow::handleNewPeerList(QString &peerListString) 158 | { 159 | this->peerList.clear(); 160 | if(peerListString.isEmpty()) 161 | return; 162 | 163 | QString username, comment; 164 | QHostAddress ip; 165 | int port; 166 | QStringList peerInfoList = peerListString.split(";"); 167 | foreach(QString peerInfo, peerInfoList) 168 | { 169 | comment = QString(""); 170 | QStringList items = peerInfo.split("@"); 171 | username = items.at(0); 172 | QString addr = items.at(1); 173 | QStringList addrList = addr.split(":"); 174 | QString ipString = addrList.at(0); 175 | ip = QHostAddress(ipString); 176 | QString portString = addrList.at(1); 177 | port = portString.toInt(); 178 | PeerInfo *pinfo = new PeerInfo(this, username, ip, port); 179 | this->peerList.push_back(pinfo); 180 | } 181 | 182 | this->updateListWidget(); 183 | } 184 | 185 | void MainWindow::handlePassiveConnection(ChatConnection *connection) 186 | { 187 | if(DEBUG) 188 | qDebug() << "New passive chat connection."; 189 | 190 | QString greeting = this->userName + ":" + this->localServerIP.toString() + ":" + QString::number(this->localServerPort); 191 | connection->setGreetingMessage(greeting); 192 | 193 | this->addChatConnection(connection); 194 | 195 | connect(connection, SIGNAL(socketError(ChatConnection*,QAbstractSocket::SocketError)), 196 | this, SLOT(handleChatConnectionError(ChatConnection*,QAbstractSocket::SocketError))); 197 | connect(connection, SIGNAL(endGreeting(ChatConnection*)), this, SLOT(handlePassiveNewChat(ChatConnection*))); 198 | } 199 | 200 | void MainWindow::handleActiveConnection() 201 | { 202 | if(DEBUG) 203 | qDebug() << "New active chat connection."; 204 | 205 | QListWidgetItem *item = this->peerListWidget->currentItem(); 206 | if(!item) 207 | { 208 | QMessageBox::warning(this, tr("Warning"), tr("Please select one peer.")); 209 | 210 | if(DEBUG) 211 | qDebug() << "Select no peer to connect."; 212 | return; 213 | } 214 | 215 | QString connInfo = item->text(); 216 | QStringList strList = connInfo.split("@"); 217 | QString name = strList.at(0); 218 | QString addr = strList.at(1); 219 | QStringList addrList = addr.split(":"); 220 | QString ipStr = addrList.at(0); 221 | QString portExtStr = addrList.at(1); 222 | QHostAddress ip = QHostAddress(ipStr); 223 | QStringList eList = portExtStr.split(" "); 224 | QString portStr = eList.at(0); 225 | int port = portStr.toInt(); 226 | 227 | if(name == this->userName && ipStr == this->localServerIP.toString() && port == this->localServerPort) 228 | { 229 | QMessageBox::warning(this, tr("Warning"), tr("Cannot select local server.")); 230 | 231 | if(DEBUG) 232 | qDebug() << "Select local server to connect."; 233 | 234 | return; 235 | } 236 | 237 | ChatConnection *cp = this->findChatConnection(name, ipStr); 238 | if(cp) 239 | { 240 | QMessageBox::warning(this, tr("Warning"), tr("Connection already established.")); 241 | 242 | if(DEBUG) 243 | qDebug() << "New error: Connection already established."; 244 | return; 245 | } 246 | 247 | if(DEBUG) 248 | { 249 | qDebug() << "Establish chat connection to selected peer."; 250 | qDebug() << "Remote peer ip: " << ip.toString(); 251 | qDebug() << "Remote peer port: " << port; 252 | } 253 | 254 | ChatConnection *newConnection = new ChatConnection(this); 255 | QString greeting = this->userName + ":" + this->localServerIP.toString() + ":" + QString::number(this->localServerPort); 256 | newConnection->setGreetingMessage(greeting); 257 | newConnection->connectToHost(ip, port); 258 | this->addChatConnection(newConnection); 259 | connect(newConnection, SIGNAL(socketError(ChatConnection*, QAbstractSocket::SocketError)), 260 | this, SLOT(handleChatConnectionError(ChatConnection*, QAbstractSocket::SocketError))); 261 | connect(newConnection, SIGNAL(endGreeting(ChatConnection*)), this, SLOT(handleNewChatDialog(ChatConnection*))); 262 | 263 | if(DEBUG) 264 | qDebug() << "Open new chat dialog to display chat process."; 265 | } 266 | 267 | void MainWindow::handleNewChatDialog(ChatConnection *connection) 268 | { 269 | QString peerName = connection->getPeerName(); 270 | QString peerAddr = connection->getPeerIP() + ":" + QString::number(connection->getPeerPort()); 271 | 272 | ChatDialog *newChat = new ChatDialog(this, this->userName, peerName, peerAddr, connection); 273 | connect(newChat, SIGNAL(dialogExit(ChatConnection*)), this, SLOT(handleDialogExit(ChatConnection*))); 274 | newChat->show(); 275 | } 276 | 277 | void MainWindow::handleDialogExit(ChatConnection *connection) 278 | { 279 | this->removeChatConnection(connection); 280 | } 281 | 282 | void MainWindow::handleCheckDialog() 283 | { 284 | QListWidgetItem *item = this->peerListWidget->currentItem(); 285 | 286 | if(!item) 287 | { 288 | QMessageBox::warning(this, tr("Warning"), tr("Please select one peer.")); 289 | 290 | if(DEBUG) 291 | qDebug() << "Select no peer to read message."; 292 | return; 293 | } 294 | 295 | QString connInfo = item->text(); 296 | QStringList strList = connInfo.split("@"); 297 | QString name = strList.at(0); 298 | QString addr = strList.at(1); 299 | QStringList addrList = addr.split(":"); 300 | QString ipStr = addrList.at(0); 301 | 302 | ChatConnection *cp = this->findChatConnection(name, ipStr); 303 | if(!cp) 304 | { 305 | QMessageBox::warning(this, tr("Warning"), tr("No connection or connection broked.")); 306 | 307 | if(DEBUG) 308 | qDebug() << "No connection or connection broked."; 309 | return; 310 | } 311 | 312 | ChatDialog *newChat = new ChatDialog(this, this->userName, name, addr, cp); 313 | connect(newChat, SIGNAL(dialogExit(ChatConnection*)), this, SLOT(handleDialogExit(ChatConnection*))); 314 | QList hList = this->tempMsgs[name]; 315 | newChat->readAndDisplayHistory(hList); 316 | this->tempMsgs.remove(name); 317 | this->updateListWidget(); 318 | newChat->show(); 319 | } 320 | 321 | void MainWindow::handlePassiveNewChat(ChatConnection *connection) 322 | { 323 | QList rcvInfoMsgs; 324 | QString name = connection->getPeerName(); 325 | this->tempMsgs.insert(name, rcvInfoMsgs); 326 | connect(connection, SIGNAL(newMessage(QString, QString)), this, SLOT(handlePassiveMsgRecv(QString, QString))); 327 | } 328 | 329 | void MainWindow::handlePassiveMsgRecv(QString from, QString msg) 330 | { 331 | QDateTime time = QDateTime::currentDateTime(); 332 | QString timeString = time.toString("hh:mm:ss MM-dd"); 333 | QString infoString = from + "(" + timeString + "): \n"; 334 | QString infoMsg = infoString + msg + "\n"; 335 | this->tempMsgs[from].push_back(infoMsg); 336 | this->updateListWidget(); 337 | 338 | if(DEBUG) 339 | qDebug() << "Handle passive received messages done."; 340 | } 341 | 342 | void MainWindow::handleChatConnectionError(ChatConnection *connection, QAbstractSocket::SocketError error) 343 | { 344 | if(DEBUG) 345 | qDebug() << "Chat connection Error."; 346 | 347 | QString errorString; 348 | switch(error) 349 | { 350 | case QAbstractSocket::ConnectionRefusedError: 351 | errorString = "Connection refused!"; 352 | break; 353 | case QAbstractSocket::RemoteHostClosedError: 354 | errorString = "Remote host closed."; 355 | break; 356 | case QAbstractSocket::HostNotFoundError: 357 | errorString = "Host not found!"; 358 | break; 359 | case QAbstractSocket::NetworkError: 360 | errorString = "Network error!"; 361 | break; 362 | case QAbstractSocket::AddressInUseError: 363 | errorString = "Address already in use!"; 364 | break; 365 | case QAbstractSocket::UnknownSocketError: 366 | default: 367 | errorString = "Unknown socket error!"; 368 | break; 369 | } 370 | connection->close(); 371 | this->removeChatConnection(connection); 372 | 373 | if(DEBUG) 374 | { 375 | qDebug() << "Chat connection error: " << errorString; 376 | qDebug() << "Handle chat connection error done."; 377 | } 378 | } 379 | 380 | void MainWindow::handleRegisterError(QAbstractSocket::SocketError error) 381 | { 382 | if(DEBUG) 383 | qDebug() << "Register network error."; 384 | 385 | QString errorString; 386 | switch(error) 387 | { 388 | case QAbstractSocket::ConnectionRefusedError: 389 | errorString = "Connection refused!"; 390 | break; 391 | case QAbstractSocket::RemoteHostClosedError: 392 | errorString = "Remote host closed."; 393 | break; 394 | case QAbstractSocket::HostNotFoundError: 395 | errorString = "Host not found!"; 396 | break; 397 | case QAbstractSocket::NetworkError: 398 | errorString = "Network error!"; 399 | break; 400 | case QAbstractSocket::AddressInUseError: 401 | errorString = "Address already in use!"; 402 | break; 403 | case QAbstractSocket::UnknownSocketError: 404 | default: 405 | errorString = "Unknown socket error!"; 406 | break; 407 | } 408 | this->server->close(); 409 | this->registConnection->close(); 410 | this->peerList.clear(); 411 | this->peerListWidget->clear(); 412 | this->registerButton->setEnabled(true); 413 | this->remoteServerLabel->setText("Not set register server info."); 414 | 415 | QMessageBox::warning(this, tr("Register Error"), errorString); 416 | 417 | if(DEBUG) 418 | qDebug() << "Handle register network error done."; 419 | } 420 | 421 | void MainWindow::addChatConnection(ChatConnection *connection) 422 | { 423 | this->connList.push_back(connection); 424 | 425 | if(DEBUG) 426 | qDebug() << "Add new chat connection to connection list."; 427 | } 428 | 429 | void MainWindow::removeChatConnection(ChatConnection *connection) 430 | { 431 | this->connList.removeOne(connection); 432 | 433 | if(DEBUG) 434 | qDebug() << "Remove chat connection from connection list"; 435 | } 436 | 437 | ChatConnection * MainWindow::findChatConnection(QString name, QString ip) 438 | { 439 | for(int i = 0; i < this->connList.size(); i++) 440 | { 441 | ChatConnection *cp = this->connList.at(i); 442 | qDebug() << "cp name: " << cp->getPeerName(); 443 | qDebug() << "cp ip: " << cp->getPeerIP(); 444 | qDebug() << "cp port" << cp->getPeerPort(); 445 | if((cp->getPeerName() == name) && 446 | (cp->getPeerIP() == ip)) 447 | return cp; 448 | } 449 | 450 | return NULL; 451 | } 452 | -------------------------------------------------------------------------------- /ChatClient/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include "header.h" 5 | #include "chatconnection.h" 6 | #include "registerconnection.h" 7 | #include "chatserver.h" 8 | #include "logindialog.h" 9 | #include "chatdialog.h" 10 | #include "peerinfo.h" 11 | #include 12 | 13 | class MainWindow : public QMainWindow 14 | { 15 | Q_OBJECT 16 | public: 17 | explicit MainWindow(QWidget *parent = 0); 18 | ~MainWindow(); 19 | 20 | signals: 21 | 22 | public slots: 23 | void handleRegisterAction(); 24 | void handleNewPeerList(QString &); 25 | void handleActiveConnection(); 26 | void handleCheckDialog(); 27 | void handlePassiveConnection(ChatConnection *); 28 | void handleChatConnectionError(ChatConnection *, QAbstractSocket::SocketError); 29 | void handleRegisterError(QAbstractSocket::SocketError); 30 | void handleNewChatDialog(ChatConnection *); 31 | void handlePassiveMsgRecv(QString, QString); 32 | void handlePassiveNewChat(ChatConnection *); 33 | void handleDialogExit(ChatConnection *); 34 | 35 | private: 36 | // private functions 37 | void initLayout(); 38 | void initNetwork(); 39 | void updateListWidget(); 40 | 41 | // connections 42 | void addChatConnection(ChatConnection *); 43 | void removeChatConnection(ChatConnection *); 44 | ChatConnection* findChatConnection(QString name, QString ip); 45 | 46 | // gui widgets 47 | QLabel *myName; 48 | QLabel *myAddress; 49 | //QLabel *myIcon; 50 | QLabel *infoLabel; 51 | QListWidget *peerListWidget; 52 | QPushButton *chatButton; 53 | QPushButton *registerButton; 54 | QPushButton *checkButton; 55 | QLabel *remoteServerLabel; 56 | 57 | // Variables 58 | QString userName; // Local Server UserName 59 | QHostAddress localServerIP; 60 | int localServerPort; 61 | QHostAddress remoteServerIP; 62 | int remoteServerPort; 63 | 64 | // connections 65 | QMap> tempMsgs; //记录被动连接的接收信息 66 | QMap chatMap; //记录已打开的ChatDialog 67 | QList peerList; // 记录活跃的远端主机 68 | QList connList; // 用于管理所有聊天连接 69 | ChatServer *server; // 本地聊天连接监听服务器 70 | RegisterConnection *registConnection; // 与中心服务器相连接 71 | }; 72 | 73 | #endif // MAINWINDOW_H 74 | -------------------------------------------------------------------------------- /ChatClient/peerinfo.cpp: -------------------------------------------------------------------------------- 1 | #include "peerinfo.h" 2 | 3 | static const int TimeOut = 22 * 1000; 4 | 5 | PeerInfo::PeerInfo(QObject *parent, QString peername, QHostAddress ip, int port) : 6 | QObject(parent) 7 | { 8 | this->setPeerInfo(peername, ip, port); 9 | } 10 | 11 | PeerInfo::~PeerInfo() 12 | { 13 | } 14 | 15 | QString PeerInfo::getPeerName() 16 | { 17 | return this->peerName; 18 | } 19 | 20 | QString PeerInfo::getPeerIP() 21 | { 22 | return this->peerIP.toString(); 23 | } 24 | 25 | int PeerInfo::getPeerPort() 26 | { 27 | return this->peerPort; 28 | } 29 | 30 | void PeerInfo::setPeerInfo(QString peername, QHostAddress ip, int port) 31 | { 32 | this->peerName = peername; 33 | this->peerIP = ip; 34 | this->peerPort = port; 35 | } 36 | 37 | void PeerInfo::clear() 38 | { 39 | 40 | } 41 | -------------------------------------------------------------------------------- /ChatClient/peerinfo.h: -------------------------------------------------------------------------------- 1 | #ifndef PEERINFO_H 2 | #define PEERINFO_H 3 | 4 | #include "header.h" 5 | #include 6 | 7 | class PeerInfo : public QObject 8 | { 9 | Q_OBJECT 10 | public: 11 | explicit PeerInfo(QObject *parent = 0, QString peername = "unknown", QHostAddress ip = QHostAddress("127.0.0.1"), int port = 0); 12 | ~PeerInfo(); 13 | 14 | QString getPeerName(); 15 | QString getPeerIP(); 16 | int getPeerPort(); 17 | void setPeerInfo(QString, QHostAddress, int); 18 | void clear(); 19 | 20 | private: 21 | QString peerName; 22 | QHostAddress peerIP; 23 | int peerPort; 24 | }; 25 | 26 | #endif // PEERINFO_H 27 | -------------------------------------------------------------------------------- /ChatClient/registerconnection.cpp: -------------------------------------------------------------------------------- 1 | #include "registerconnection.h" 2 | 3 | static const int TransferTimeout = 40 * 1000; 4 | static const int PeriodicInterval = 15 * 1000; 5 | static const char SeparateToken = ' '; 6 | 7 | RegisterConnection::RegisterConnection(QObject *parent) : 8 | QTcpSocket(parent) 9 | { 10 | this->greetingMessage = QObject::tr("Register Validation"); 11 | this->registerMessage = QObject::tr(" "); 12 | this->state = WaitingForGreeting; 13 | this->currentDataType = UNDEFINED; 14 | this->isGreetingMessageSent = false; 15 | this->numBytesForCurrentDataType = -1; 16 | this->transferTimerId = 0; 17 | this->periodicTimer.setInterval(PeriodicInterval); 18 | 19 | connect(this, SIGNAL(readyRead()), this, SLOT(processReadyRead())); 20 | connect(&periodicTimer, SIGNAL(timeout()), this, SLOT(sendPeriodicRegisterMessage())); 21 | connect(this, SIGNAL(connected()), this, SLOT(sendGreetingMessage())); 22 | } 23 | 24 | void RegisterConnection::setLocalServerInfo(QString &name, QHostAddress &ip, int &port) 25 | { 26 | this->localUserName = name; 27 | this->localServerIP = ip; 28 | this->localServerPort = port; 29 | this->registerMessage = this->localUserName + '@' + 30 | this->localServerIP.toString() + ':' + 31 | QString::number(this->localServerPort); 32 | this->greetingMessage = this->localUserName + ':' + 33 | this->localServerIP.toString() + ':' + 34 | QString::number(this->localServerPort); 35 | } 36 | 37 | void RegisterConnection::timerEvent(QTimerEvent *timerEvent) 38 | { 39 | if(timerEvent->timerId() == this->transferTimerId) 40 | { 41 | this->abort(); 42 | this->killTimer(transferTimerId); 43 | transferTimerId = 0; 44 | } 45 | } 46 | 47 | void RegisterConnection::sendGreetingMessage() 48 | { 49 | QByteArray greet = this->greetingMessage.toUtf8(); 50 | QByteArray msg = "GREETING " + QByteArray::number(greet.size()) + ' ' + greet; 51 | if(this->write(msg) == msg.size()) 52 | { 53 | if(DEBUG) 54 | qDebug() << "Send greeting message!"; 55 | this->isGreetingMessageSent = 1; 56 | 57 | this->sendPeriodicRegisterMessage(); 58 | this->periodicTimer.start(); 59 | if(DEBUG) 60 | qDebug() << "Send register message!"; 61 | } 62 | } 63 | 64 | bool RegisterConnection::sendPeriodicRegisterMessage() 65 | { 66 | QByteArray regist = this->registerMessage.toUtf8(); 67 | QByteArray msg = "REGISTER " + QByteArray::number(regist.size()) + ' ' + regist; 68 | return this->write(msg) == msg.size(); 69 | } 70 | 71 | int RegisterConnection::readDataIntoBuffer(int maxSize) 72 | { 73 | if(maxSize > MaxBufferSize) 74 | return 0; 75 | 76 | int numBytesBeforeRead = this->buffer.size(); 77 | if(numBytesBeforeRead >= MaxBufferSize) 78 | { 79 | this->abort(); 80 | return 0; 81 | } 82 | 83 | while(this->bytesAvailable() > 0 && buffer.size() <= maxSize) 84 | { 85 | this->buffer.append(this->read(1)); 86 | if(buffer.endsWith(SeparateToken)) 87 | break; 88 | } 89 | 90 | return buffer.size() - numBytesBeforeRead; 91 | } 92 | 93 | int RegisterConnection::dataLengthForCurrentDataType() 94 | { 95 | if(this->bytesAvailable() <=0 || this->readDataIntoBuffer() <= 0 || !this->buffer.endsWith(SeparateToken)) 96 | return 0; 97 | 98 | this->buffer.chop(1); 99 | int length = this->buffer.toInt(); 100 | this->buffer.clear(); 101 | 102 | return length; 103 | } 104 | 105 | bool RegisterConnection::hasEnoughData() 106 | { 107 | if(this->transferTimerId != 0) 108 | { 109 | this->killTimer(this->transferTimerId); 110 | this->transferTimerId = 0; 111 | } 112 | 113 | if(this->numBytesForCurrentDataType <= 0) 114 | this->numBytesForCurrentDataType = this->dataLengthForCurrentDataType(); 115 | 116 | if(bytesAvailable() < this->numBytesForCurrentDataType || this->numBytesForCurrentDataType <= 0) 117 | { 118 | this->transferTimerId = this->startTimer(TransferTimeout); 119 | return false; 120 | } 121 | 122 | return true; 123 | } 124 | 125 | void RegisterConnection::processReadyRead() 126 | { 127 | if(this->state == WaitingForGreeting) 128 | { 129 | if(!readProtocolHeader()) 130 | return; 131 | if(this->currentDataType != GREETING) 132 | { 133 | this->abort(); 134 | return; 135 | } 136 | 137 | this->state = ReadingGreeting; 138 | } 139 | 140 | if(this->state == ReadingGreeting) 141 | { 142 | if(!this->hasEnoughData()) 143 | return; 144 | 145 | this->buffer = this->read(this->numBytesForCurrentDataType); 146 | if(this->buffer.size() != this->numBytesForCurrentDataType) 147 | { 148 | this->abort(); 149 | return; 150 | } 151 | 152 | this->buffer.clear(); 153 | this->numBytesForCurrentDataType = -1; 154 | this->currentDataType = UNDEFINED; 155 | 156 | if(!this->isValid()) 157 | { 158 | this->abort(); 159 | return; 160 | } 161 | 162 | if(!this->isGreetingMessageSent) 163 | this->sendGreetingMessage(); 164 | 165 | this->state = ReadyForUse; 166 | } 167 | 168 | do 169 | { 170 | if(currentDataType == UNDEFINED) 171 | { 172 | if(!readProtocolHeader()) 173 | return; 174 | } 175 | 176 | if(!this->hasEnoughData()) 177 | return; 178 | 179 | this->processData(); 180 | }while(this->bytesAvailable() > 0); 181 | } 182 | 183 | bool RegisterConnection::readProtocolHeader() 184 | { 185 | if(this->transferTimerId != 0) 186 | { 187 | this->killTimer(this->transferTimerId); 188 | this->transferTimerId = 0; 189 | } 190 | 191 | if(this->readDataIntoBuffer() <= 0) 192 | { 193 | this->transferTimerId = this->startTimer(TransferTimeout); 194 | return false; 195 | } 196 | 197 | if(this->buffer == "GREETING ") 198 | this->currentDataType = GREETING; 199 | else if (this->buffer == "REGISTER ") 200 | this->currentDataType = REGISTER; 201 | else if (this->buffer == "PEERLIST ") 202 | this->currentDataType = PEERLIST; 203 | else 204 | { 205 | this->currentDataType = UNDEFINED; 206 | this->abort(); 207 | return false; 208 | } 209 | 210 | this->buffer.clear(); 211 | this->numBytesForCurrentDataType = this->dataLengthForCurrentDataType(); 212 | return true; 213 | } 214 | 215 | void RegisterConnection::processData() 216 | { 217 | this->buffer = this->read(this->numBytesForCurrentDataType); 218 | if(this->buffer.size() != this->numBytesForCurrentDataType) 219 | { 220 | this->abort(); 221 | return; 222 | } 223 | 224 | switch(this->currentDataType) 225 | { 226 | case REGISTER: 227 | break; 228 | case PEERLIST: 229 | this->peerListString = QString::fromUtf8(this->buffer); 230 | emit this->newPeerList(this->peerListString); 231 | break; 232 | default: 233 | break; 234 | } 235 | 236 | this->currentDataType = UNDEFINED; 237 | this->numBytesForCurrentDataType = -1; 238 | this->buffer.clear(); 239 | } 240 | -------------------------------------------------------------------------------- /ChatClient/registerconnection.h: -------------------------------------------------------------------------------- 1 | /* 说明: 2 | * RegisterConnection用于与中心验证服务器通信,主要交换Register注册信息和PeerList活跃用户信息 3 | * 这里,我们也有几个设计说明: 4 | * (1) 我们仍然设置Greeting的过程用于初始的连接建立过程 5 | * (2) 我们设置周期定时器用于周期发送Register信息和获取最新的活跃用户信息 6 | * 7 | */ 8 | 9 | #ifndef REGISTERCONNECTION_H 10 | #define REGISTERCONNECTION_H 11 | 12 | #include "header.h" 13 | #include 14 | 15 | 16 | class RegisterConnection : public QTcpSocket 17 | { 18 | Q_OBJECT 19 | public: 20 | explicit RegisterConnection(QObject *parent = 0); 21 | 22 | enum RegisterConnectionState 23 | { 24 | WaitingForGreeting, 25 | ReadingGreeting, 26 | ReadyForUse 27 | }; 28 | 29 | enum DataType 30 | { 31 | GREETING, 32 | REGISTER, 33 | PEERLIST, 34 | UNDEFINED 35 | }; 36 | 37 | void setLocalServerInfo(QString &name, QHostAddress &ip, int &port); 38 | 39 | signals: 40 | void newPeerList(QString &peerlist); 41 | 42 | protected: 43 | void timerEvent(QTimerEvent *); 44 | 45 | public slots: 46 | void processReadyRead(); 47 | void sendGreetingMessage(); 48 | bool sendPeriodicRegisterMessage(); 49 | 50 | private: 51 | int readDataIntoBuffer(int maxSize = MaxBufferSize); 52 | int dataLengthForCurrentDataType(); 53 | bool readProtocolHeader(); 54 | bool hasEnoughData(); 55 | void processData(); 56 | 57 | QString localUserName; 58 | QHostAddress localServerIP; 59 | int localServerPort; 60 | 61 | QByteArray buffer; 62 | QTimer periodicTimer; 63 | QString peerListString; 64 | QString greetingMessage; 65 | QString registerMessage; 66 | enum RegisterConnectionState state; 67 | enum DataType currentDataType; 68 | int numBytesForCurrentDataType; 69 | int transferTimerId; 70 | bool isGreetingMessageSent; 71 | }; 72 | 73 | #endif // REGISTERCONNECTION_H 74 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Material/P2P聊天软件设计文档.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adomy/P2PChatRoom/7871062b5125fdda109ed8506e692e749c60e878/Material/P2P聊天软件设计文档.pdf -------------------------------------------------------------------------------- /Material/chat_dialog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adomy/P2PChatRoom/7871062b5125fdda109ed8506e692e749c60e878/Material/chat_dialog.jpg -------------------------------------------------------------------------------- /Material/chat_dialog2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adomy/P2PChatRoom/7871062b5125fdda109ed8506e692e749c60e878/Material/chat_dialog2.jpg -------------------------------------------------------------------------------- /Material/client_gui.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adomy/P2PChatRoom/7871062b5125fdda109ed8506e692e749c60e878/Material/client_gui.jpg -------------------------------------------------------------------------------- /Material/client_gui2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adomy/P2PChatRoom/7871062b5125fdda109ed8506e692e749c60e878/Material/client_gui2.jpg -------------------------------------------------------------------------------- /Material/register_gui.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adomy/P2PChatRoom/7871062b5125fdda109ed8506e692e749c60e878/Material/register_gui.jpg -------------------------------------------------------------------------------- /Material/register_server_gui.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adomy/P2PChatRoom/7871062b5125fdda109ed8506e692e749c60e878/Material/register_server_gui.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | P2P聊天软件设计 2 | ======================================================================================== 3 | 4 | ## 功能要求 5 | * 用户界面(GUI)可自行设计,主要为用户提供方便。 6 | * 用户界面要及时的对用户的操作做出反应。 7 | * 要实现一个用户可以和多个用户同时进行聊天。 8 | 9 | ## 设计目标及流程 10 | 设计一个P2P聊天软件,由多个聊天客户端和一个中心服务器组成。各个聊天客户端可以两两相互发送消息。目的在于设计GUI、多线程和套接字编程。各个客户端用IP地址和TCP/IP监听端口号进行标识。每个客户提供一个名字,方便其它客户端。 11 | 12 | 此设计由两部分组成。 13 | 14 | ### 第一部分:注册 15 | P2P聊天中各个成员管理。每个成员称为一个peer,要有一个中心的服务处理peer的登记和对已经登记的peer进行更新。 16 | * 步骤1:一个peer选择一个名字,通过登记界面进行登记。 17 | * 步骤2:服务器拥有一个公有IP,在一个众所周知的端口进行监听。Peer向服务器发送‘register’请求,同时发送自己的登记信息(如己取的名字,自己的监听端口号等)。服务器收到‘register’请求后,如果这是每一个登记请求,服务器建立一个用于记录已经登记peer的列表(Peer List),否则更新Peer List。 18 | * 步骤3:服务器向来登记的peer发送Peer List。PeerList 由一些活跃的peer组成,一个活跃的peer是在最近30秒内进行登记的peer。 19 | * 步骤4:peer收到 Peer List后,以适当的形式显示出来。设计一个显示Peer List的GUI。 20 | * 步骤5:每个已经登记的peer每隔15秒向服务器登记,来使自己保持活跃,同时得到最近新登记的peer信息。如果需要,就在自己的PeerList GUI进行更新。 21 | 22 | ### 第二部分:交互 23 | 多个peer间相互发送消息。 24 | * 步骤1:在的客户端P1的用户U1(U1@P1)在自己Peer List GUI中选择一个peer,假设为U2@P2。 25 | * 步骤2:P1建立一个到P2的连接。 26 | * 步骤3:U1在自己的发送信息界面(Messaging GUI)编写信息,然后点击发送按钮,P1将信息通过步骤2中建立的连接发送到P2。 27 | * 步骤4:如果第3个用户U3@P3发送一条消息到U1@P1,如果U1此时正好有一个Messaging GUI与U3进行交互,那么就显示消息,如果没有,就要提示U1有新消息到来。两个User之间可以相互发送消息,每对User之间有一个单独的Messaging GUI。 28 | 29 | ## 软件组成 30 | 本软件由ChatClient和RegisterServer两部分组成,其中ChatClient为客户端,可执行注册和聊天过程,而RegisterServer为注册服务器,主要用于注册客户端和分发注册客户端信息。 31 | 32 | ## 版本更新日志 33 | v0.1 34 | + 构建出基础的软件结构,并未实现多线程(多进程)编程<使用了Qt的异步封装> 35 | + 通信机制还应该有所改善,不应该直接弹出聊天框,可以实现如QQ的消息提醒方式 36 | + 界面亟需改善 37 | 38 | ## 软件运行界面 39 | * 客户端注册界面 40 | 41 | ![客户端注册界面](https://raw.githubusercontent.com/adoryn/P2PChatRoom/master/Material/register_gui.jpg) 42 | 43 | * 客户端界面 44 | 45 | ![客户端界面](https://raw.githubusercontent.com/adoryn/P2PChatRoom/master/Material/client_gui.jpg) 46 | 47 | ![客户端界面(新消息)](https://raw.githubusercontent.com/adoryn/P2PChatRoom/master/Material/client_gui2.jpg) 48 | 49 | * 注册服务器界面 50 | 51 | ![注册服务器界面](https://raw.githubusercontent.com/adoryn/P2PChatRoom/master/Material/register_server_gui.jpg) 52 | 53 | * 客户端通信聊天界面 54 | 55 | ![客户端通信聊天界面](https://raw.githubusercontent.com/adoryn/P2PChatRoom/master/Material/chat_dialog.jpg) 56 | 57 | 备注:由于个人不会界面设计,因此界面十分粗糙。同时由于功能的相对不完善,因此,对于整个软件的架构设计还有一些方面的不完善,后面估计会考虑去重构该软件。 58 | -------------------------------------------------------------------------------- /RegisterServer/Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # Makefile for building: RegisterServer 3 | # Generated by qmake (3.0) (Qt 5.6.0) 4 | # Project: RegisterServer.pro 5 | # Template: app 6 | # Command: C:\Qt\Qt5.6.0\5.6\mingw49_32\bin\qmake.exe -spec win32-g++ "CONFIG+=debug" "CONFIG+=qml_debug" -o Makefile RegisterServer.pro 7 | ############################################################################# 8 | 9 | MAKEFILE = Makefile 10 | 11 | first: debug 12 | install: debug-install 13 | uninstall: debug-uninstall 14 | QMAKE = C:\Qt\Qt5.6.0\5.6\mingw49_32\bin\qmake.exe 15 | DEL_FILE = del 16 | CHK_DIR_EXISTS= if not exist 17 | MKDIR = mkdir 18 | COPY = copy /y 19 | COPY_FILE = copy /y 20 | COPY_DIR = xcopy /s /q /y /i 21 | INSTALL_FILE = copy /y 22 | INSTALL_PROGRAM = copy /y 23 | INSTALL_DIR = xcopy /s /q /y /i 24 | DEL_FILE = del 25 | SYMLINK = $(QMAKE) -install ln -f -s 26 | DEL_DIR = rmdir 27 | MOVE = move 28 | SUBTARGETS = \ 29 | debug \ 30 | release 31 | 32 | 33 | debug: FORCE 34 | $(MAKE) -f $(MAKEFILE).Debug 35 | debug-make_first: FORCE 36 | $(MAKE) -f $(MAKEFILE).Debug 37 | debug-all: FORCE 38 | $(MAKE) -f $(MAKEFILE).Debug all 39 | debug-clean: FORCE 40 | $(MAKE) -f $(MAKEFILE).Debug clean 41 | debug-distclean: FORCE 42 | $(MAKE) -f $(MAKEFILE).Debug distclean 43 | debug-install: FORCE 44 | $(MAKE) -f $(MAKEFILE).Debug install 45 | debug-uninstall: FORCE 46 | $(MAKE) -f $(MAKEFILE).Debug uninstall 47 | release: FORCE 48 | $(MAKE) -f $(MAKEFILE).Release 49 | release-make_first: FORCE 50 | $(MAKE) -f $(MAKEFILE).Release 51 | release-all: FORCE 52 | $(MAKE) -f $(MAKEFILE).Release all 53 | release-clean: FORCE 54 | $(MAKE) -f $(MAKEFILE).Release clean 55 | release-distclean: FORCE 56 | $(MAKE) -f $(MAKEFILE).Release distclean 57 | release-install: FORCE 58 | $(MAKE) -f $(MAKEFILE).Release install 59 | release-uninstall: FORCE 60 | $(MAKE) -f $(MAKEFILE).Release uninstall 61 | 62 | Makefile: RegisterServer.pro ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/win32-g++/qmake.conf ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/spec_pre.prf \ 63 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/qdevice.pri \ 64 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/device_config.prf \ 65 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/common/angle.conf \ 66 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/qconfig.pri \ 67 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dcore.pri \ 68 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dcore_private.pri \ 69 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dinput.pri \ 70 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dinput_private.pri \ 71 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dlogic.pri \ 72 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dlogic_private.pri \ 73 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquick.pri \ 74 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquick_private.pri \ 75 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquickinput.pri \ 76 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquickinput_private.pri \ 77 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquickrender.pri \ 78 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquickrender_private.pri \ 79 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3drender.pri \ 80 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3drender_private.pri \ 81 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axbase.pri \ 82 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axbase_private.pri \ 83 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axcontainer.pri \ 84 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axcontainer_private.pri \ 85 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axserver.pri \ 86 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axserver_private.pri \ 87 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_bluetooth.pri \ 88 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_bluetooth_private.pri \ 89 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_bootstrap_private.pri \ 90 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_clucene_private.pri \ 91 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_concurrent.pri \ 92 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_concurrent_private.pri \ 93 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_core.pri \ 94 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_core_private.pri \ 95 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_dbus.pri \ 96 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_dbus_private.pri \ 97 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_designer.pri \ 98 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_designer_private.pri \ 99 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_designercomponents_private.pri \ 100 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_gui.pri \ 101 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_gui_private.pri \ 102 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_help.pri \ 103 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_help_private.pri \ 104 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_labscontrols_private.pri \ 105 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_labstemplates_private.pri \ 106 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_location.pri \ 107 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_location_private.pri \ 108 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_multimedia.pri \ 109 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_multimedia_private.pri \ 110 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_multimediawidgets.pri \ 111 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_multimediawidgets_private.pri \ 112 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_network.pri \ 113 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_network_private.pri \ 114 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_nfc.pri \ 115 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_nfc_private.pri \ 116 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_opengl.pri \ 117 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_opengl_private.pri \ 118 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_openglextensions.pri \ 119 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_openglextensions_private.pri \ 120 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_platformsupport_private.pri \ 121 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_positioning.pri \ 122 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_positioning_private.pri \ 123 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_printsupport.pri \ 124 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_printsupport_private.pri \ 125 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qml.pri \ 126 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qml_private.pri \ 127 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qmldevtools_private.pri \ 128 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qmltest.pri \ 129 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qmltest_private.pri \ 130 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qtmultimediaquicktools_private.pri \ 131 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quick.pri \ 132 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quick_private.pri \ 133 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quickparticles_private.pri \ 134 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quickwidgets.pri \ 135 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quickwidgets_private.pri \ 136 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_script.pri \ 137 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_script_private.pri \ 138 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_scripttools.pri \ 139 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_scripttools_private.pri \ 140 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_sensors.pri \ 141 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_sensors_private.pri \ 142 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_serialbus.pri \ 143 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_serialbus_private.pri \ 144 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_serialport.pri \ 145 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_serialport_private.pri \ 146 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_sql.pri \ 147 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_sql_private.pri \ 148 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_svg.pri \ 149 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_svg_private.pri \ 150 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_testlib.pri \ 151 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_testlib_private.pri \ 152 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_uiplugin.pri \ 153 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_uitools.pri \ 154 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_uitools_private.pri \ 155 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_webchannel.pri \ 156 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_webchannel_private.pri \ 157 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_websockets.pri \ 158 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_websockets_private.pri \ 159 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_widgets.pri \ 160 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_widgets_private.pri \ 161 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_winextras.pri \ 162 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_winextras_private.pri \ 163 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_xml.pri \ 164 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_xml_private.pri \ 165 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_xmlpatterns.pri \ 166 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_xmlpatterns_private.pri \ 167 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/qt_functions.prf \ 168 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/qt_config.prf \ 169 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/qt_config.prf \ 170 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/win32-g++/qmake.conf \ 171 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/spec_post.prf \ 172 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/exclusive_builds.prf \ 173 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/default_pre.prf \ 174 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/default_pre.prf \ 175 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/resolve_config.prf \ 176 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/exclusive_builds_post.prf \ 177 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/default_post.prf \ 178 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/qml_debug.prf \ 179 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/rtti.prf \ 180 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/precompile_header.prf \ 181 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/warn_on.prf \ 182 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/qt.prf \ 183 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/resources.prf \ 184 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/moc.prf \ 185 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/opengl.prf \ 186 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/uic.prf \ 187 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/windows.prf \ 188 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/testcase_targets.prf \ 189 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/exceptions.prf \ 190 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/yacc.prf \ 191 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/lex.prf \ 192 | RegisterServer.pro \ 193 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/qtmaind.prl \ 194 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/Qt5Widgets.prl \ 195 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/Qt5Gui.prl \ 196 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/Qt5Network.prl \ 197 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/Qt5Core.prl 198 | $(QMAKE) -spec win32-g++ "CONFIG+=debug" "CONFIG+=qml_debug" -o Makefile RegisterServer.pro 199 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/spec_pre.prf: 200 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/qdevice.pri: 201 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/device_config.prf: 202 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/common/angle.conf: 203 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/qconfig.pri: 204 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dcore.pri: 205 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dcore_private.pri: 206 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dinput.pri: 207 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dinput_private.pri: 208 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dlogic.pri: 209 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dlogic_private.pri: 210 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquick.pri: 211 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquick_private.pri: 212 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquickinput.pri: 213 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquickinput_private.pri: 214 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquickrender.pri: 215 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3dquickrender_private.pri: 216 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3drender.pri: 217 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_3drender_private.pri: 218 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axbase.pri: 219 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axbase_private.pri: 220 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axcontainer.pri: 221 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axcontainer_private.pri: 222 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axserver.pri: 223 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_axserver_private.pri: 224 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_bluetooth.pri: 225 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_bluetooth_private.pri: 226 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_bootstrap_private.pri: 227 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_clucene_private.pri: 228 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_concurrent.pri: 229 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_concurrent_private.pri: 230 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_core.pri: 231 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_core_private.pri: 232 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_dbus.pri: 233 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_dbus_private.pri: 234 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_designer.pri: 235 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_designer_private.pri: 236 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_designercomponents_private.pri: 237 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_gui.pri: 238 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_gui_private.pri: 239 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_help.pri: 240 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_help_private.pri: 241 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_labscontrols_private.pri: 242 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_labstemplates_private.pri: 243 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_location.pri: 244 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_location_private.pri: 245 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_multimedia.pri: 246 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_multimedia_private.pri: 247 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_multimediawidgets.pri: 248 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_multimediawidgets_private.pri: 249 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_network.pri: 250 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_network_private.pri: 251 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_nfc.pri: 252 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_nfc_private.pri: 253 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_opengl.pri: 254 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_opengl_private.pri: 255 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_openglextensions.pri: 256 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_openglextensions_private.pri: 257 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_platformsupport_private.pri: 258 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_positioning.pri: 259 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_positioning_private.pri: 260 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_printsupport.pri: 261 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_printsupport_private.pri: 262 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qml.pri: 263 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qml_private.pri: 264 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qmldevtools_private.pri: 265 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qmltest.pri: 266 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qmltest_private.pri: 267 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_qtmultimediaquicktools_private.pri: 268 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quick.pri: 269 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quick_private.pri: 270 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quickparticles_private.pri: 271 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quickwidgets.pri: 272 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_quickwidgets_private.pri: 273 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_script.pri: 274 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_script_private.pri: 275 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_scripttools.pri: 276 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_scripttools_private.pri: 277 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_sensors.pri: 278 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_sensors_private.pri: 279 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_serialbus.pri: 280 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_serialbus_private.pri: 281 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_serialport.pri: 282 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_serialport_private.pri: 283 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_sql.pri: 284 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_sql_private.pri: 285 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_svg.pri: 286 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_svg_private.pri: 287 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_testlib.pri: 288 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_testlib_private.pri: 289 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_uiplugin.pri: 290 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_uitools.pri: 291 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_uitools_private.pri: 292 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_webchannel.pri: 293 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_webchannel_private.pri: 294 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_websockets.pri: 295 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_websockets_private.pri: 296 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_widgets.pri: 297 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_widgets_private.pri: 298 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_winextras.pri: 299 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_winextras_private.pri: 300 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_xml.pri: 301 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_xml_private.pri: 302 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_xmlpatterns.pri: 303 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/modules/qt_lib_xmlpatterns_private.pri: 304 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/qt_functions.prf: 305 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/qt_config.prf: 306 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/qt_config.prf: 307 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/win32-g++/qmake.conf: 308 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/spec_post.prf: 309 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/exclusive_builds.prf: 310 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/default_pre.prf: 311 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/default_pre.prf: 312 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/resolve_config.prf: 313 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/exclusive_builds_post.prf: 314 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/default_post.prf: 315 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/qml_debug.prf: 316 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/rtti.prf: 317 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/precompile_header.prf: 318 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/warn_on.prf: 319 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/qt.prf: 320 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/resources.prf: 321 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/moc.prf: 322 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/opengl.prf: 323 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/uic.prf: 324 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/win32/windows.prf: 325 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/testcase_targets.prf: 326 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/exceptions.prf: 327 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/yacc.prf: 328 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/mkspecs/features/lex.prf: 329 | RegisterServer.pro: 330 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/qtmaind.prl: 331 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/Qt5Widgets.prl: 332 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/Qt5Gui.prl: 333 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/Qt5Network.prl: 334 | ../../../../Qt/Qt5.6.0/5.6/mingw49_32/lib/Qt5Core.prl: 335 | qmake: FORCE 336 | @$(QMAKE) -spec win32-g++ "CONFIG+=debug" "CONFIG+=qml_debug" -o Makefile RegisterServer.pro 337 | 338 | qmake_all: FORCE 339 | 340 | make_first: debug-make_first release-make_first FORCE 341 | all: debug-all release-all FORCE 342 | clean: debug-clean release-clean FORCE 343 | distclean: debug-distclean release-distclean FORCE 344 | -$(DEL_FILE) Makefile 345 | 346 | debug-mocclean: 347 | $(MAKE) -f $(MAKEFILE).Debug mocclean 348 | release-mocclean: 349 | $(MAKE) -f $(MAKEFILE).Release mocclean 350 | mocclean: debug-mocclean release-mocclean 351 | 352 | debug-mocables: 353 | $(MAKE) -f $(MAKEFILE).Debug mocables 354 | release-mocables: 355 | $(MAKE) -f $(MAKEFILE).Release mocables 356 | mocables: debug-mocables release-mocables 357 | 358 | check: first 359 | FORCE: 360 | 361 | $(MAKEFILE).Debug: Makefile 362 | $(MAKEFILE).Release: Makefile 363 | -------------------------------------------------------------------------------- /RegisterServer/RegisterServer.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2015-10-10T10:36:22 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui network 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = RegisterServer 12 | TEMPLATE = app 13 | 14 | 15 | SOURCES += main.cpp\ 16 | window.cpp \ 17 | registerconnection.cpp \ 18 | registerserver.cpp \ 19 | peerinfo.cpp 20 | 21 | HEADERS += window.h \ 22 | registerconnection.h \ 23 | header.h \ 24 | registerserver.h \ 25 | peerinfo.h 26 | 27 | RC_FILE += images/icon.rc 28 | 29 | OTHER_FILES += \ 30 | images/icon.rc \ 31 | images/server.ico 32 | 33 | 34 | -------------------------------------------------------------------------------- /RegisterServer/RegisterServer.pro.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | EnvironmentId 7 | {1f2d4bf0-dd7c-4612-97c0-0e08f39cb8c2} 8 | 9 | 10 | ProjectExplorer.Project.ActiveTarget 11 | 0 12 | 13 | 14 | ProjectExplorer.Project.EditorSettings 15 | 16 | true 17 | false 18 | true 19 | 20 | Cpp 21 | 22 | CppGlobal 23 | 24 | 25 | 26 | QmlJS 27 | 28 | QmlJSGlobal 29 | 30 | 31 | 2 32 | UTF-8 33 | false 34 | 4 35 | false 36 | 80 37 | true 38 | true 39 | 1 40 | true 41 | false 42 | 0 43 | true 44 | 0 45 | 8 46 | true 47 | 1 48 | true 49 | true 50 | true 51 | false 52 | 53 | 54 | 55 | ProjectExplorer.Project.PluginSettings 56 | 57 | 58 | 59 | ProjectExplorer.Project.Target.0 60 | 61 | Desktop Qt 5.6.0 MinGW 32bit 62 | Desktop Qt 5.6.0 MinGW 32bit 63 | qt.56.win32_mingw49_kit 64 | 0 65 | 0 66 | 0 67 | 68 | C:/Users/Adoryn/P2PChatRoom/RegisterServer 69 | 70 | 71 | true 72 | qmake 73 | 74 | QtProjectManager.QMakeBuildStep 75 | true 76 | 77 | false 78 | false 79 | false 80 | 81 | 82 | true 83 | Make 84 | 85 | Qt4ProjectManager.MakeStep 86 | 87 | false 88 | 89 | 90 | 91 | 2 92 | 构建 93 | 94 | ProjectExplorer.BuildSteps.Build 95 | 96 | 97 | 98 | true 99 | Make 100 | 101 | Qt4ProjectManager.MakeStep 102 | 103 | true 104 | clean 105 | 106 | 107 | 1 108 | 清理 109 | 110 | ProjectExplorer.BuildSteps.Clean 111 | 112 | 2 113 | false 114 | 115 | Debug 116 | 117 | Qt4ProjectManager.Qt4BuildConfiguration 118 | 2 119 | true 120 | 121 | 122 | C:/Users/Adoryn/P2PChatRoom/build-RegisterServer-Desktop_Qt_5_6_0_MinGW_32bit-Release 123 | 124 | 125 | true 126 | qmake 127 | 128 | QtProjectManager.QMakeBuildStep 129 | false 130 | 131 | false 132 | false 133 | false 134 | 135 | 136 | true 137 | Make 138 | 139 | Qt4ProjectManager.MakeStep 140 | 141 | false 142 | 143 | 144 | 145 | 2 146 | 构建 147 | 148 | ProjectExplorer.BuildSteps.Build 149 | 150 | 151 | 152 | true 153 | Make 154 | 155 | Qt4ProjectManager.MakeStep 156 | 157 | true 158 | clean 159 | 160 | 161 | 1 162 | 清理 163 | 164 | ProjectExplorer.BuildSteps.Clean 165 | 166 | 2 167 | false 168 | 169 | Release 170 | 171 | Qt4ProjectManager.Qt4BuildConfiguration 172 | 0 173 | true 174 | 175 | 176 | C:/Users/Adoryn/P2PChatRoom/build-RegisterServer-Desktop_Qt_5_6_0_MinGW_32bit-Profile 177 | 178 | 179 | true 180 | qmake 181 | 182 | QtProjectManager.QMakeBuildStep 183 | true 184 | 185 | false 186 | true 187 | false 188 | 189 | 190 | true 191 | Make 192 | 193 | Qt4ProjectManager.MakeStep 194 | 195 | false 196 | 197 | 198 | 199 | 2 200 | 构建 201 | 202 | ProjectExplorer.BuildSteps.Build 203 | 204 | 205 | 206 | true 207 | Make 208 | 209 | Qt4ProjectManager.MakeStep 210 | 211 | true 212 | clean 213 | 214 | 215 | 1 216 | 清理 217 | 218 | ProjectExplorer.BuildSteps.Clean 219 | 220 | 2 221 | false 222 | 223 | Profile 224 | 225 | Qt4ProjectManager.Qt4BuildConfiguration 226 | 0 227 | true 228 | 229 | 3 230 | 231 | 232 | 0 233 | 部署 234 | 235 | ProjectExplorer.BuildSteps.Deploy 236 | 237 | 1 238 | 在本地部署 239 | 240 | ProjectExplorer.DefaultDeployConfiguration 241 | 242 | 1 243 | 244 | 245 | false 246 | 1000 247 | 248 | true 249 | 250 | false 251 | false 252 | false 253 | false 254 | true 255 | 0.01 256 | 10 257 | true 258 | 1 259 | 25 260 | 261 | 1 262 | true 263 | false 264 | true 265 | valgrind 266 | 267 | 0 268 | 1 269 | 2 270 | 3 271 | 4 272 | 5 273 | 6 274 | 7 275 | 8 276 | 9 277 | 10 278 | 11 279 | 12 280 | 13 281 | 14 282 | 283 | 2 284 | 285 | RegisterServer 286 | 287 | Qt4ProjectManager.Qt4RunConfiguration:C:/Users/Adoryn/P2PChatRoom/RegisterServer/RegisterServer.pro 288 | true 289 | 290 | RegisterServer.pro 291 | false 292 | false 293 | 294 | 3768 295 | false 296 | true 297 | false 298 | false 299 | true 300 | 301 | 1 302 | 303 | 304 | 305 | ProjectExplorer.Project.TargetCount 306 | 1 307 | 308 | 309 | ProjectExplorer.Project.Updater.FileVersion 310 | 18 311 | 312 | 313 | Version 314 | 18 315 | 316 | 317 | -------------------------------------------------------------------------------- /RegisterServer/debug.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adomy/P2PChatRoom/7871062b5125fdda109ed8506e692e749c60e878/RegisterServer/debug.log -------------------------------------------------------------------------------- /RegisterServer/header.h: -------------------------------------------------------------------------------- 1 | #ifndef HEADER_H 2 | #define HEADER_H 3 | 4 | // General Methods 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | // Widgets 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | // Notification Methods 39 | #include 40 | 41 | // Qt Network 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | 49 | // Related to Json File operations 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | #define MaxBufferSize 1024000 56 | #define DEBUG 1 57 | 58 | #endif // HEADER_H 59 | -------------------------------------------------------------------------------- /RegisterServer/images/icon.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "server.ico" -------------------------------------------------------------------------------- /RegisterServer/images/server.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adomy/P2PChatRoom/7871062b5125fdda109ed8506e692e749c60e878/RegisterServer/images/server.ico -------------------------------------------------------------------------------- /RegisterServer/main.cpp: -------------------------------------------------------------------------------- 1 | #include "window.h" 2 | #include "header.h" 3 | #include 4 | 5 | void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg); 6 | void clearLogFile(); 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | clearLogFile(); 11 | qInstallMessageHandler(outputMessage); 12 | QApplication a(argc, argv); 13 | Window w; 14 | w.show(); 15 | 16 | return a.exec(); 17 | } 18 | 19 | void clearLogFile() 20 | { 21 | QFile file("registerLog.txt"); 22 | file.open(QIODevice::WriteOnly | QIODevice::Append); 23 | file.resize(0); 24 | file.flush(); 25 | file.close(); 26 | } 27 | 28 | void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg) 29 | { 30 | static QMutex mutex; 31 | 32 | QString text; 33 | switch(type) 34 | { 35 | case QtDebugMsg: 36 | text = QString("Debug:"); 37 | break; 38 | 39 | case QtWarningMsg: 40 | text = QString("Warning:"); 41 | break; 42 | 43 | case QtCriticalMsg: 44 | text = QString("Critical:"); 45 | break; 46 | 47 | case QtFatalMsg: 48 | text = QString("Fatal:"); 49 | break; 50 | 51 | default: 52 | break; 53 | } 54 | 55 | QString context_info = QString("(%1:%2)").arg(QString(context.file)).arg(context.line); 56 | QString message = QString("%1 %2 %3").arg(text).arg(context_info).arg(msg); 57 | 58 | mutex.lock(); 59 | 60 | QFile file("registerLog.txt"); 61 | file.open(QIODevice::WriteOnly | QIODevice::Append); 62 | QTextStream text_stream(&file); 63 | text_stream << message << "\r\n"; 64 | file.flush(); 65 | file.close(); 66 | 67 | mutex.unlock(); 68 | } 69 | -------------------------------------------------------------------------------- /RegisterServer/peerinfo.cpp: -------------------------------------------------------------------------------- 1 | #include "peerinfo.h" 2 | 3 | static const int TimeOut = 22 * 1000; 4 | 5 | PeerInfo::PeerInfo(QObject *parent, QString peername, QHostAddress ip, int port) : 6 | QObject(parent) 7 | { 8 | this->setPeerInfo(peername, ip, port); 9 | this->state = true; 10 | this->activeTimer = new QTimer(); 11 | this->activeTimer->setInterval(TimeOut); 12 | this->activeTimer->start(); 13 | 14 | if(DEBUG) 15 | qDebug() << "PeerInfo active timer started."; 16 | connect(activeTimer, SIGNAL(timeout()), this, SLOT(handleTimeOut())); 17 | } 18 | 19 | PeerInfo::~PeerInfo() 20 | { 21 | } 22 | 23 | QString PeerInfo::getPeerName() 24 | { 25 | return this->peerName; 26 | } 27 | 28 | QString PeerInfo::getPeerIP() 29 | { 30 | return this->peerIP.toString(); 31 | } 32 | 33 | int PeerInfo::getPeerPort() 34 | { 35 | return this->peerPort; 36 | } 37 | 38 | void PeerInfo::setPeerInfo(QString peername, QHostAddress ip, int port) 39 | { 40 | this->peerName = peername; 41 | this->peerIP = ip; 42 | this->peerPort = port; 43 | } 44 | 45 | void PeerInfo::handleTimeOut() 46 | { 47 | this->state = false; 48 | this->activeTimer->stop(); 49 | emit this->peerExpire(this); 50 | } 51 | 52 | void PeerInfo::refresh() 53 | { 54 | if(this->state == false) 55 | this->state = true; 56 | 57 | this->activeTimer->setInterval(TimeOut); 58 | this->activeTimer->start(); 59 | } 60 | 61 | void PeerInfo::clear() 62 | { 63 | this->state = true; 64 | this->activeTimer->stop(); 65 | } 66 | 67 | 68 | -------------------------------------------------------------------------------- /RegisterServer/peerinfo.h: -------------------------------------------------------------------------------- 1 | #ifndef PEERINFO_H 2 | #define PEERINFO_H 3 | 4 | #include "header.h" 5 | #include 6 | 7 | class PeerInfo : public QObject 8 | { 9 | Q_OBJECT 10 | public: 11 | explicit PeerInfo(QObject *parent = 0, QString peername = "unknown", QHostAddress ip = QHostAddress("127.0.0.1"), int port = 0); 12 | ~PeerInfo(); 13 | 14 | QString getPeerName(); 15 | QString getPeerIP(); 16 | int getPeerPort(); 17 | void setPeerInfo(QString, QHostAddress, int); 18 | void refresh(); 19 | void clear(); 20 | 21 | signals: 22 | void peerExpire(PeerInfo *); 23 | 24 | public slots: 25 | void handleTimeOut(); 26 | 27 | private: 28 | QString peerName; 29 | QHostAddress peerIP; 30 | int peerPort; 31 | bool state; 32 | 33 | QTimer *activeTimer; 34 | }; 35 | 36 | #endif // PEERINFO_H 37 | -------------------------------------------------------------------------------- /RegisterServer/registerLog.txt: -------------------------------------------------------------------------------- 1 | Debug: (window.cpp:113) Register server ip address: "192.168.1.174" 2 | Debug: (window.cpp:114) Register server port: 10001 3 | Debug: (window.cpp:128) Register server started. 4 | Debug: (window.cpp:170) Handle new connection. 5 | Debug: (window.cpp:379) Add new connection into registerConns. 6 | Debug: (registerconnection.cpp:156) Get greeting message: "unknown:192.168.1.174:9001" 7 | Debug: (registerconnection.cpp:166) Received greeting message: "unknown:192.168.1.174:9001" 8 | Debug: (window.cpp:184) Enter handle_new_register_msg function: 9 | Debug: (window.cpp:185) New register message: "unknown@192.168.1.174:9001" 10 | Debug: (window.cpp:199) Register message information: 11 | Debug: (window.cpp:200) Hostname: "unknown" 12 | Debug: (window.cpp:201) IP address: "192.168.1.174" 13 | Debug: (window.cpp:202) Port: "9001" 14 | Debug: (peerinfo.cpp:15) PeerInfo active timer started. 15 | Debug: (window.cpp:400) Add new PeerInfo into peerList: "unknown" 16 | Debug: (window.cpp:359) Broadcast peerList changed message 17 | Debug: (window.cpp:340) Generate PeerList String. 18 | Debug: (window.cpp:369) Broadcast message sent. 19 | Debug: (window.cpp:228) Handle new register msg done. 20 | Debug: (window.cpp:252) Register connection network error. 21 | Debug: (window.cpp:279) Register connection error: "Remote host closed." 22 | Debug: (window.cpp:410) Remove PeerInfo from peerList "unknown" 23 | Debug: (window.cpp:390) Remove connection from registerConns. 24 | Debug: (window.cpp:359) Broadcast peerList changed message 25 | Debug: (window.cpp:340) Generate PeerList String. 26 | Debug: (window.cpp:369) Broadcast message sent. 27 | Debug: (window.cpp:291) Handle network error done. 28 | Debug: (window.cpp:147) Register server stopped! 29 | -------------------------------------------------------------------------------- /RegisterServer/registerconnection.cpp: -------------------------------------------------------------------------------- 1 | #include "registerconnection.h" 2 | 3 | static const int TransferTimeout = 40 * 1000; 4 | static const char SeparateToken = ' '; 5 | 6 | RegisterConnection::RegisterConnection(QObject *parent) : 7 | QTcpSocket(parent) 8 | { 9 | this->greetingMessage = QString("Register Validation"); 10 | this->registerMessage = QString(""); 11 | this->state = WaitingForGreeting; 12 | this->currentDataType = UNDEFINED; 13 | this->isGreetingMessageSent = false; 14 | this->numBytesForCurrentDataType = -1; 15 | this->transferTimerId = 0; 16 | 17 | connect(this, SIGNAL(readyRead()), this, SLOT(processReadyRead())); 18 | connect(this, SIGNAL(connected()), this, SLOT(sendGreetingMessage())); 19 | connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(handleSocketError(QAbstractSocket::SocketError))); 20 | } 21 | 22 | RegisterConnection::~RegisterConnection() 23 | { 24 | 25 | } 26 | 27 | QString RegisterConnection::getPeerServerName() 28 | { 29 | return this->name; 30 | } 31 | 32 | QHostAddress RegisterConnection::getPeerServerIP() 33 | { 34 | return this->ip; 35 | } 36 | 37 | int RegisterConnection::getPeerServerPort() 38 | { 39 | return this->port; 40 | } 41 | 42 | void RegisterConnection::handleSocketError(QAbstractSocket::SocketError error) 43 | { 44 | emit this->registerError(this, error); 45 | } 46 | 47 | void RegisterConnection::timerEvent(QTimerEvent *timerEvent) 48 | { 49 | if(timerEvent->timerId() == this->transferTimerId) 50 | { 51 | this->abort(); 52 | this->killTimer(transferTimerId); 53 | transferTimerId = 0; 54 | } 55 | } 56 | 57 | void RegisterConnection::sendGreetingMessage() 58 | { 59 | QByteArray greet = this->greetingMessage.toUtf8(); 60 | QByteArray msg = "GREETING " + QByteArray::number(greet.size()) + ' ' + greet; 61 | if(this->write(msg) == msg.size()) 62 | this->isGreetingMessageSent = 1; 63 | } 64 | 65 | bool RegisterConnection::sendPeriodicPeerlistMessage(QString message) 66 | { 67 | QByteArray peerStr = message.toUtf8(); 68 | QByteArray msg = "PEERLIST " + QByteArray::number(peerStr.size()) + ' ' + peerStr; 69 | return this->write(msg) == msg.size(); 70 | } 71 | 72 | int RegisterConnection::readDataIntoBuffer(int maxSize) 73 | { 74 | if(maxSize > MaxBufferSize) 75 | return 0; 76 | 77 | int numBytesBeforeRead = this->buffer.size(); 78 | if(numBytesBeforeRead >= MaxBufferSize) 79 | { 80 | this->abort(); 81 | return 0; 82 | } 83 | 84 | while(this->bytesAvailable() > 0 && buffer.size() <= maxSize) 85 | { 86 | this->buffer.append(this->read(1)); 87 | if(buffer.endsWith(SeparateToken)) 88 | break; 89 | } 90 | 91 | return buffer.size() - numBytesBeforeRead; 92 | } 93 | 94 | int RegisterConnection::dataLengthForCurrentDataType() 95 | { 96 | if(this->bytesAvailable() <=0 || this->readDataIntoBuffer() <= 0 || !this->buffer.endsWith(SeparateToken)) 97 | return 0; 98 | 99 | this->buffer.chop(1); 100 | int length = this->buffer.toInt(); 101 | this->buffer.clear(); 102 | 103 | return length; 104 | } 105 | 106 | bool RegisterConnection::hasEnoughData() 107 | { 108 | if(this->transferTimerId != 0) 109 | { 110 | this->killTimer(this->transferTimerId); 111 | this->transferTimerId = 0; 112 | } 113 | 114 | if(this->numBytesForCurrentDataType <= 0) 115 | this->numBytesForCurrentDataType = this->dataLengthForCurrentDataType(); 116 | 117 | if(bytesAvailable() < this->numBytesForCurrentDataType || this->numBytesForCurrentDataType <= 0) 118 | { 119 | this->transferTimerId = this->startTimer(TransferTimeout); 120 | return false; 121 | } 122 | 123 | return true; 124 | } 125 | 126 | void RegisterConnection::processReadyRead() 127 | { 128 | if(this->state == WaitingForGreeting) 129 | { 130 | if(!readProtocolHeader()) 131 | return; 132 | if(this->currentDataType != GREETING) 133 | { 134 | this->abort(); 135 | return; 136 | } 137 | 138 | this->state = ReadingGreeting; 139 | } 140 | 141 | if(this->state == ReadingGreeting) 142 | { 143 | if(!this->hasEnoughData()) 144 | return; 145 | 146 | this->buffer = this->read(this->numBytesForCurrentDataType); 147 | if(this->buffer.size() != this->numBytesForCurrentDataType) 148 | { 149 | this->abort(); 150 | return; 151 | } 152 | 153 | QString greeting = QString::fromUtf8(this->buffer); 154 | 155 | if(DEBUG) 156 | qDebug() << "Get greeting message: " << greeting; 157 | 158 | QStringList addrList = greeting.split(":"); 159 | this->name = addrList.at(0); 160 | QString ipStr = addrList.at(1); 161 | QString portStr = addrList.at(2); 162 | this->ip = QHostAddress(ipStr); 163 | this->port = portStr.toInt(); 164 | 165 | if(DEBUG) 166 | qDebug() << "Received greeting message: " << QString::fromUtf8(this->buffer); 167 | 168 | this->buffer.clear(); 169 | this->numBytesForCurrentDataType = -1; 170 | this->currentDataType = UNDEFINED; 171 | 172 | if(!this->isValid()) 173 | { 174 | this->abort(); 175 | return; 176 | } 177 | 178 | if(!this->isGreetingMessageSent) 179 | this->sendGreetingMessage(); 180 | 181 | this->state = ReadyForUse; 182 | } 183 | 184 | do 185 | { 186 | if(currentDataType == UNDEFINED) 187 | { 188 | if(!readProtocolHeader()) 189 | return; 190 | } 191 | 192 | if(!this->hasEnoughData()) 193 | return; 194 | 195 | this->processData(); 196 | }while(this->bytesAvailable() > 0); 197 | } 198 | 199 | bool RegisterConnection::readProtocolHeader() 200 | { 201 | if(this->transferTimerId != 0) 202 | { 203 | this->killTimer(this->transferTimerId); 204 | this->transferTimerId = 0; 205 | } 206 | 207 | if(this->readDataIntoBuffer() <= 0) 208 | { 209 | this->transferTimerId = this->startTimer(TransferTimeout); 210 | return false; 211 | } 212 | 213 | if(this->buffer == "GREETING ") 214 | this->currentDataType = GREETING; 215 | else if (this->buffer == "REGISTER ") 216 | this->currentDataType = REGISTER; 217 | else if (this->buffer == "PEERLIST ") 218 | this->currentDataType = PEERLIST; 219 | else 220 | { 221 | this->currentDataType = UNDEFINED; 222 | this->abort(); 223 | return false; 224 | } 225 | 226 | this->buffer.clear(); 227 | this->numBytesForCurrentDataType = this->dataLengthForCurrentDataType(); 228 | return true; 229 | } 230 | 231 | void RegisterConnection::processData() 232 | { 233 | this->buffer = this->read(this->numBytesForCurrentDataType); 234 | if(this->buffer.size() != this->numBytesForCurrentDataType) 235 | { 236 | this->abort(); 237 | return; 238 | } 239 | 240 | switch(this->currentDataType) 241 | { 242 | case REGISTER: 243 | this->registerMessage = QString::fromUtf8(this->buffer); 244 | emit this->newRegisterMsg(this, this->registerMessage); 245 | break; 246 | case PEERLIST: 247 | break; 248 | default: 249 | break; 250 | } 251 | 252 | this->currentDataType = UNDEFINED; 253 | this->numBytesForCurrentDataType = -1; 254 | this->buffer.clear(); 255 | } 256 | -------------------------------------------------------------------------------- /RegisterServer/registerconnection.h: -------------------------------------------------------------------------------- 1 | /* 说明: 2 | * RegisterConnection用于与中心验证服务器通信,主要交换Register注册信息和PeerList活跃用户信息 3 | * 这里,我们也有几个设计说明: 4 | * (1) 我们仍然设置Greeting的过程用于初始的连接建立过程 5 | * (2) 我们设置周期定时器用于周期发送Register信息和获取最新的活跃用户信息 6 | * 7 | */ 8 | 9 | #ifndef REGISTERCONNECTION_H 10 | #define REGISTERCONNECTION_H 11 | 12 | #include "header.h" 13 | #include 14 | 15 | class RegisterConnection : public QTcpSocket 16 | { 17 | Q_OBJECT 18 | public: 19 | enum RegisterConnectionState 20 | { 21 | WaitingForGreeting, 22 | ReadingGreeting, 23 | ReadyForUse 24 | }; 25 | 26 | enum DataType 27 | { 28 | GREETING, 29 | REGISTER, 30 | PEERLIST, 31 | UNDEFINED 32 | }; 33 | 34 | explicit RegisterConnection(QObject *parent = 0); 35 | ~RegisterConnection(); 36 | 37 | QString getPeerServerName(); 38 | QHostAddress getPeerServerIP(); 39 | int getPeerServerPort(); 40 | 41 | signals: 42 | void newRegisterMsg(RegisterConnection *, QString); 43 | void registerError(RegisterConnection *, QAbstractSocket::SocketError); 44 | 45 | protected: 46 | void timerEvent(QTimerEvent *); 47 | 48 | public slots: 49 | void processReadyRead(); 50 | void sendGreetingMessage(); 51 | bool sendPeriodicPeerlistMessage(QString message); 52 | void handleSocketError(QAbstractSocket::SocketError); 53 | 54 | private: 55 | 56 | // receive 57 | int readDataIntoBuffer(int maxSize = MaxBufferSize); 58 | int dataLengthForCurrentDataType(); 59 | bool readProtocolHeader(); 60 | bool hasEnoughData(); 61 | void processData(); 62 | 63 | QString name; 64 | QHostAddress ip; 65 | int port; 66 | 67 | QByteArray buffer; 68 | enum RegisterConnectionState state; 69 | enum DataType currentDataType; 70 | int numBytesForCurrentDataType; 71 | int transferTimerId; 72 | bool isGreetingMessageSent; 73 | QString greetingMessage; 74 | QString registerMessage; 75 | }; 76 | 77 | #endif // REGISTERCONNECTION_H 78 | -------------------------------------------------------------------------------- /RegisterServer/registerserver.cpp: -------------------------------------------------------------------------------- 1 | #include "registerserver.h" 2 | 3 | RegisterServer::RegisterServer(QObject *parent) : 4 | QTcpServer(parent) 5 | { 6 | } 7 | 8 | void RegisterServer::setServerInfo(QHostAddress ip, int port) 9 | { 10 | this->myPort = port; 11 | this->myIP = ip; 12 | } 13 | 14 | bool RegisterServer::startServer() 15 | { 16 | return this->listen(this->myIP, this->myPort); 17 | } 18 | 19 | void RegisterServer::incomingConnection(qintptr socketDescriptor) 20 | { 21 | RegisterConnection *connection = new RegisterConnection(this); 22 | connection->setSocketDescriptor(socketDescriptor); 23 | emit newRegisterConnection(connection); 24 | } 25 | -------------------------------------------------------------------------------- /RegisterServer/registerserver.h: -------------------------------------------------------------------------------- 1 | #ifndef REGISTERSERVER_H 2 | #define REGISTERSERVER_H 3 | 4 | #include "header.h" 5 | #include "registerconnection.h" 6 | #include 7 | 8 | class RegisterServer : public QTcpServer 9 | { 10 | Q_OBJECT 11 | public: 12 | explicit RegisterServer(QObject *parent = 0); 13 | 14 | void setServerInfo(QHostAddress ip, int port); 15 | bool startServer(); 16 | 17 | signals: 18 | void newRegisterConnection(RegisterConnection *connection); 19 | 20 | protected: 21 | void incomingConnection(qintptr socketDescriptor); 22 | 23 | private: 24 | QHostAddress myIP; 25 | int myPort; 26 | }; 27 | 28 | #endif // REGISTERSERVER_H 29 | -------------------------------------------------------------------------------- /RegisterServer/window.cpp: -------------------------------------------------------------------------------- 1 | #include "window.h" 2 | 3 | Window::Window(QWidget *parent) 4 | : QMainWindow(parent) 5 | { 6 | this->listLabel = new QLabel(QObject::tr("Register Host List: "), this); 7 | this->registerListWidget = new QListWidget(this); 8 | this->logLabel = new QLabel(QObject::tr("Register Log: "), this); 9 | this->logRegister = new QTextEdit(this); 10 | this->ipLabel = new QLabel(QObject::tr("Server IP:"), this); 11 | this->ipBox = new QComboBox(this); 12 | this->ipLabel->setBuddy(this->ipBox); 13 | this->portLabel = new QLabel(QObject::tr("Server Port:"), this); 14 | this->portBox = new QSpinBox(this); 15 | this->portLabel->setBuddy(this->portBox); 16 | 17 | this->networkInterfacesCombo(); 18 | this->portBox->setRange(1024, 65535); 19 | this->portBox->setValue(10001); 20 | 21 | this->startButton = new QPushButton(QObject::tr("Start"), this); 22 | this->stopButton = new QPushButton(QObject::tr("Stop"), this); 23 | this->logRegister->setReadOnly(true); 24 | this->startButton->setFocusPolicy(Qt::StrongFocus); 25 | this->stopButton->setEnabled(false); 26 | 27 | this->peerList.clear(); 28 | this->registerConns.clear(); 29 | this->serverIP = QHostAddress("127.0.0.1"); 30 | this->serverPort = 10001; 31 | this->server = new RegisterServer(); 32 | 33 | this->initLayout(); 34 | this->resize(QSize(550, 360)); 35 | 36 | connect(startButton, SIGNAL(clicked()), this, SLOT(startNetwork())); 37 | connect(stopButton, SIGNAL(clicked()), this, SLOT(stopNetwork())); 38 | } 39 | 40 | Window::~Window() 41 | { 42 | this->server->close(); 43 | } 44 | 45 | // 通过读取网卡接口的信息获取本机的所有IP地址,并通过QComboBox呈现 46 | void Window::networkInterfacesCombo() 47 | { 48 | QList list = QNetworkInterface::allAddresses(); 49 | foreach( QHostAddress address, list ) 50 | { 51 | if(address.protocol() == QAbstractSocket::IPv4Protocol) 52 | this->ipBox->addItem(address.toString()); 53 | } 54 | } 55 | 56 | // 设置整个Window的界面布局 57 | void Window::initLayout() 58 | { 59 | QVBoxLayout *listLayout = new QVBoxLayout; 60 | listLayout->addWidget(this->listLabel); 61 | listLayout->addWidget(this->registerListWidget); 62 | 63 | QHBoxLayout *ipLayout = new QHBoxLayout; 64 | ipLayout->addWidget(this->ipLabel); 65 | ipLayout->addWidget(this->ipBox); 66 | ipLayout->setStretch(0, 1); 67 | ipLayout->setStretch(1, 3); 68 | 69 | QHBoxLayout *portLayout = new QHBoxLayout; 70 | portLayout->addWidget(this->portLabel); 71 | portLayout->addWidget(this->portBox); 72 | portLayout->setStretch(0, 1); 73 | portLayout->setStretch(1, 3); 74 | 75 | QVBoxLayout *logLayout = new QVBoxLayout; 76 | logLayout->addWidget(this->logLabel); 77 | logLayout->addWidget(this->logRegister); 78 | logLayout->addLayout(ipLayout); 79 | logLayout->addLayout(portLayout); 80 | 81 | QHBoxLayout *buttonLayout = new QHBoxLayout; 82 | buttonLayout->addStretch(); 83 | buttonLayout->addWidget(this->startButton); 84 | buttonLayout->addWidget(this->stopButton); 85 | 86 | QHBoxLayout *hLayout = new QHBoxLayout; 87 | hLayout->addLayout(listLayout); 88 | hLayout->addLayout(logLayout); 89 | hLayout->setStretch(0, 2); 90 | hLayout->setStretch(1, 3); 91 | 92 | QVBoxLayout *mainLayout = new QVBoxLayout; 93 | mainLayout->addLayout(hLayout); 94 | mainLayout->addLayout(buttonLayout); 95 | mainLayout->setStretch(1, 8); 96 | mainLayout->setStretch(2, 1); 97 | 98 | QWidget *widget = new QWidget(this); 99 | widget->setLayout(mainLayout); 100 | 101 | this->setCentralWidget(widget); 102 | } 103 | 104 | // 启动中心注册服务器 105 | void Window::startNetwork() 106 | { 107 | // 获取控件中的地址信息,包括IP地址和端口号 108 | QString ip = this->ipBox->currentText(); 109 | this->serverIP = QHostAddress(ip); 110 | this->serverPort = this->portBox->value(); 111 | if(DEBUG) 112 | { 113 | qDebug() << "Register server ip address: " << this->serverIP.toString(); 114 | qDebug() << "Register server port: " << this->serverPort; 115 | } 116 | 117 | // 设置服务器信息以及启动服务器 118 | this->server->setServerInfo(this->serverIP, this->serverPort); 119 | if(this->server->startServer()) 120 | { 121 | this->startButton->setEnabled(false); 122 | this->ipBox->setEnabled(false); 123 | this->portBox->setEnabled(false); 124 | this->stopButton->setEnabled(true); 125 | this->appendLogInfo("Register server started."); 126 | 127 | if(DEBUG) 128 | qDebug() << "Register server started."; 129 | } 130 | else 131 | { 132 | QMessageBox::warning(this, tr("Error"), tr("Cannot start register server!")); 133 | this->appendLogInfo("Cannot start register server."); 134 | 135 | if(DEBUG) 136 | qDebug() << "Cannot start register server."; 137 | return; 138 | } 139 | 140 | connect(this->server, SIGNAL(newRegisterConnection(RegisterConnection *)), this, SLOT(handleNewConnection(RegisterConnection *))); 141 | } 142 | 143 | // 停止注册中心服务器 144 | void Window::stopNetwork() 145 | { 146 | if(DEBUG) 147 | qDebug() << "Register server stopped!"; 148 | this->appendLogInfo("Register server stopped."); 149 | this->server->close(); 150 | for(int i = 0; i < this->registerConns.size(); i++) 151 | { 152 | RegisterConnection *c = this->registerConns.at(i); 153 | c->close(); 154 | } 155 | this->peerList.clear(); 156 | this->registerConns.clear(); 157 | 158 | // Widget update 159 | this->registerListWidget->clear(); 160 | this->startButton->setEnabled(true); 161 | this->ipBox->setEnabled(true); 162 | this->portBox->setEnabled(true); 163 | this->stopButton->setEnabled(false); 164 | } 165 | 166 | // 处理新建立的连接,即当有远端客户端发起注册请求时,建立TCP连接,发送注册信息 167 | void Window::handleNewConnection(RegisterConnection *connection) 168 | { 169 | if(DEBUG) 170 | qDebug() << "Handle new connection."; 171 | 172 | this->addRegisterConnection(connection); 173 | 174 | connect(connection, SIGNAL(newRegisterMsg(RegisterConnection *, QString)), this, SLOT(handleNewRegisterMsg(RegisterConnection *, QString))); 175 | connect(connection, SIGNAL(registerError(RegisterConnection*,QAbstractSocket::SocketError)), 176 | this, SLOT(handleRegisterError(RegisterConnection*,QAbstractSocket::SocketError))); 177 | } 178 | 179 | // 处理新的注册信息,如果注册信息更新,便更新相应表项 180 | void Window::handleNewRegisterMsg(RegisterConnection *connection, QString message) 181 | { 182 | if(DEBUG) 183 | { 184 | qDebug() << "Enter handle_new_register_msg function:"; 185 | qDebug() << "New register message: " << message; 186 | } 187 | 188 | QStringList infoList = message.split("@"); 189 | QString hostName = infoList.at(0); 190 | QString addr = infoList.at(1); 191 | QStringList addrList = addr.split(":"); 192 | QString ipStr = addrList.at(0); 193 | QHostAddress ip = QHostAddress(ipStr); 194 | QString portStr = addrList.at(1); 195 | int port = portStr.toInt(); 196 | 197 | if(DEBUG) 198 | { 199 | qDebug() << "Register message information: "; 200 | qDebug() << "Hostname: " << hostName; 201 | qDebug() << "IP address:" << ipStr; 202 | qDebug() << "Port:" << portStr; 203 | } 204 | 205 | PeerInfo *pi = findPeer(hostName, ip, port); 206 | if(pi) 207 | { 208 | pi->refresh(); 209 | this->appendLogInfo("Activate exist register: " + message); 210 | if(DEBUG) 211 | qDebug() << "Active timer of PeerInfo reset."; 212 | } 213 | else 214 | { 215 | pi = new PeerInfo(this, hostName, ip, port); 216 | this->addPeerInfoIntoList(pi); 217 | connect(pi, SIGNAL(peerExpire(PeerInfo *)), this, SLOT(handlePeerTimeout(PeerInfo *))); 218 | 219 | // 刷新Register的列表控件 220 | this->updateRegisterListWidget(); 221 | this->appendLogInfo("New register: " + message); 222 | 223 | // 发送新的PeerList到远端 224 | this->broadcastPeerChange(); 225 | } 226 | 227 | if(DEBUG) 228 | qDebug() << "Handle new register msg done."; 229 | } 230 | 231 | // 处理PeerList表项过期 232 | void Window::handlePeerTimeout(PeerInfo *pi) 233 | { 234 | if(DEBUG) 235 | qDebug() << "PeerInfo expired: " << pi->getPeerName(); 236 | this->appendLogInfo("PeerInfo expired: " + pi->getPeerName()); 237 | 238 | RegisterConnection *c = this->findConnection(pi); 239 | this->removePeerInfoFromList(pi); 240 | this->removeRegisterConnection(c); 241 | this->broadcastPeerChange(); 242 | this->updateRegisterListWidget(); 243 | 244 | if(DEBUG) 245 | qDebug() << "Handle expired done."; 246 | } 247 | 248 | // 处理注册Client断线的情况 249 | void Window::handleRegisterError(RegisterConnection *connection, QAbstractSocket::SocketError error) 250 | { 251 | if(DEBUG) 252 | qDebug() << "Register connection network error."; 253 | 254 | QString errorString; 255 | switch(error) 256 | { 257 | case QAbstractSocket::ConnectionRefusedError: 258 | errorString = "Connection refused!"; 259 | break; 260 | case QAbstractSocket::RemoteHostClosedError: 261 | errorString = "Remote host closed."; 262 | break; 263 | case QAbstractSocket::HostNotFoundError: 264 | errorString = "Host not found!"; 265 | break; 266 | case QAbstractSocket::NetworkError: 267 | errorString = "Network error!"; 268 | break; 269 | case QAbstractSocket::AddressInUseError: 270 | errorString = "Address already in use!"; 271 | break; 272 | case QAbstractSocket::UnknownSocketError: 273 | default: 274 | errorString = "Unknown socket error!"; 275 | break; 276 | } 277 | 278 | if(DEBUG) 279 | qDebug() << "Register connection error: " << errorString; 280 | 281 | this->appendLogInfo("Connection Error: " + errorString); 282 | PeerInfo *pi = this->findPeer(connection->getPeerServerName(), connection->getPeerServerIP(), connection->getPeerServerPort()); 283 | this->appendLogInfo("Delete register: " + pi->getPeerName()); 284 | this->removePeerInfoFromList(pi); 285 | pi->clear(); 286 | this->removeRegisterConnection(connection); 287 | this->broadcastPeerChange(); 288 | this->updateRegisterListWidget(); 289 | 290 | if(DEBUG) 291 | qDebug() << "Handle network error done."; 292 | } 293 | 294 | // 更新ListWidget控件信息 295 | void Window::updateRegisterListWidget() 296 | { 297 | this->registerListWidget->clear(); 298 | for(int i = 0; i < this->peerList.size(); i++) 299 | { 300 | PeerInfo *pi = this->peerList.at(i); 301 | QString itemString = pi->getPeerName() + "@" 302 | + pi->getPeerIP() + ":" 303 | + QString::number(pi->getPeerPort()); 304 | this->registerListWidget->addItem(new QListWidgetItem(itemString)); 305 | } 306 | } 307 | 308 | PeerInfo * Window::findPeer(QString name, QHostAddress ip, int port) 309 | { 310 | for(int i = 0; i < this->peerList.size(); i++) 311 | { 312 | PeerInfo *p = this->peerList.at(i); 313 | if(p->getPeerName() == name && 314 | p->getPeerIP() == ip.toString() && 315 | p->getPeerPort() == port) 316 | return p; 317 | } 318 | 319 | return NULL; 320 | } 321 | 322 | RegisterConnection * Window::findConnection(PeerInfo *pi) 323 | { 324 | qDebug() << "Enter findConnection."; 325 | for(int i = 0; i < this->registerConns.size(); i++) 326 | { 327 | RegisterConnection *c = this->registerConns.at(i); 328 | if(c->getPeerServerName() == pi->getPeerName() && 329 | c->getPeerServerIP().toString() == pi->getPeerIP() && 330 | c->getPeerServerPort() == pi->getPeerPort()) 331 | return c; 332 | } 333 | 334 | return NULL; 335 | } 336 | 337 | QString Window::genPeerListStr() 338 | { 339 | if(DEBUG) 340 | qDebug() << "Generate PeerList String."; 341 | 342 | QString peerListStr(""); 343 | for(int i = 0; i < this->peerList.size(); i++) 344 | { 345 | PeerInfo *p = this->peerList.at(i); 346 | QString peerStr = p->getPeerName() + "@" 347 | + p->getPeerIP() + ":" 348 | + QString::number(p->getPeerPort()) + ";"; 349 | peerListStr += peerStr; 350 | } 351 | peerListStr.chop(1); 352 | 353 | return peerListStr; 354 | } 355 | 356 | void Window::broadcastPeerChange() 357 | { 358 | if(DEBUG) 359 | qDebug() << "Broadcast peerList changed message"; 360 | 361 | QString str = this->genPeerListStr(); 362 | for(int i = 0; i < this->registerConns.size(); i++) 363 | { 364 | RegisterConnection *c = this->registerConns.at(i); 365 | c->sendPeriodicPeerlistMessage(str); 366 | } 367 | 368 | if(DEBUG) 369 | qDebug() << "Broadcast message sent."; 370 | } 371 | 372 | void Window::addRegisterConnection(RegisterConnection *connection) 373 | { 374 | this->mutex2.lock(); 375 | this->registerConns.push_back(connection); 376 | this->mutex2.unlock(); 377 | 378 | if(DEBUG) 379 | qDebug() << "Add new connection into registerConns."; 380 | } 381 | 382 | void Window::removeRegisterConnection(RegisterConnection *connection) 383 | { 384 | this->mutex2.lock(); 385 | this->registerConns.removeOne(connection); 386 | connection->deleteLater(); 387 | this->mutex2.unlock(); 388 | 389 | if(DEBUG) 390 | qDebug() << "Remove connection from registerConns."; 391 | } 392 | 393 | void Window::addPeerInfoIntoList(PeerInfo *pi) 394 | { 395 | this->mutex1.lock(); 396 | this->peerList.push_back(pi); 397 | this->mutex1.unlock(); 398 | 399 | if(DEBUG) 400 | qDebug() << "Add new PeerInfo into peerList:" << pi->getPeerName(); 401 | } 402 | 403 | void Window::removePeerInfoFromList(PeerInfo *pi) 404 | { 405 | this->mutex1.lock(); 406 | this->peerList.removeOne(pi); 407 | this->mutex1.unlock(); 408 | 409 | if(DEBUG) 410 | qDebug() << "Remove PeerInfo from peerList" << pi->getPeerName(); 411 | } 412 | 413 | void Window::appendLogInfo(QString msg) 414 | { 415 | QDateTime time = QDateTime::currentDateTime(); 416 | QString timeString = time.toString("yyyy-MM-dd hh:mm:ss"); 417 | this->logRegister->append(timeString + " >\n" + msg); 418 | } 419 | -------------------------------------------------------------------------------- /RegisterServer/window.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOW_H 2 | #define WINDOW_H 3 | 4 | #include "header.h" 5 | #include "peerinfo.h" 6 | #include "registerconnection.h" 7 | #include "registerserver.h" 8 | #include 9 | 10 | class Window : public QMainWindow 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | Window(QWidget *parent = 0); 16 | ~Window(); 17 | 18 | public slots: 19 | void startNetwork(); 20 | void stopNetwork(); 21 | void handleNewConnection(RegisterConnection *connection); 22 | void handleRegisterError(RegisterConnection *, QAbstractSocket::SocketError); 23 | void handleNewRegisterMsg(RegisterConnection *, QString message); 24 | void handlePeerTimeout(PeerInfo *); 25 | 26 | private: 27 | // 私有函数及方法(主要包括界面初始化、网络操作工具函数等) 28 | void initLayout(); 29 | void networkInterfacesCombo(); 30 | void updateRegisterListWidget(); 31 | void appendLogInfo(QString); 32 | 33 | QString genPeerListStr(); 34 | PeerInfo* findPeer(QString, QHostAddress, int); 35 | RegisterConnection* findConnection(PeerInfo *); 36 | 37 | void addRegisterConnection(RegisterConnection *); 38 | void removeRegisterConnection(RegisterConnection *); 39 | void addPeerInfoIntoList(PeerInfo *); 40 | void removePeerInfoFromList(PeerInfo *); 41 | void broadcastPeerChange(); 42 | 43 | // 私有成员变量(主要与网络相关) 44 | QMutex mutex1, mutex2; 45 | RegisterServer *server; 46 | QList registerConns; 47 | QList peerList; 48 | QHostAddress serverIP; 49 | int serverPort; 50 | 51 | // 私有成员变量(主要与界面相关) 52 | QLabel *listLabel; 53 | QListWidget *registerListWidget; 54 | QLabel *logLabel; 55 | QTextEdit *logRegister; 56 | QLabel *ipLabel; 57 | QComboBox *ipBox; 58 | QLabel *portLabel; 59 | QSpinBox *portBox; 60 | QPushButton *startButton; 61 | QPushButton *stopButton; 62 | 63 | }; 64 | 65 | #endif // WINDOW_H 66 | --------------------------------------------------------------------------------