├── MRoomClient ├── Config.ini ├── HBScreenShot.cpp ├── HBScreenShot.h ├── MRoomClient.pro ├── MRoomClient.pro.user ├── MRoomClient.pro.user.08fac7a ├── MRoomClient.pro.user.25b49aa.4.8-pre1 ├── header.h ├── images │ ├── resource.qrc │ └── sysTray.ico ├── logindlg.cpp ├── logindlg.h ├── logindlg.ui ├── main.cpp ├── mroomclient.cpp ├── mroomclient.h ├── mroomclient.ui ├── projectionthread.cpp ├── projectionthread.h ├── resource.qrc ├── sfile.cpp ├── sfile.h ├── sfile.ui ├── tdatasocket.cpp ├── tdatasocket.h ├── udatasocket.cpp └── udatasocket.h ├── MRoomServer ├── Config.ini ├── HBScreenShot.cpp ├── HBScreenShot.h ├── MRoomServer.pro ├── MRoomServer.pro.user ├── MRoomServer.pro.user.25b49aa.4.8-pre1 ├── header.h ├── images │ ├── close.ico │ └── closed_128px_1229164_easyicon.net.ico ├── logindlg.cpp ├── logindlg.h ├── logindlg.ui ├── main.cpp ├── monitorthread.cpp ├── monitorthread.h ├── mroomserver.cpp ├── mroomserver.h ├── mroomserver.ui ├── mserverthread.cpp ├── mserverthread.h ├── remotecontroldlg.cpp ├── remotecontroldlg.h ├── remotecontroldlg.ui ├── resource.qrc ├── sfile.cpp ├── sfile.h ├── sfile.ui ├── sfserver.cpp ├── sfserver.h ├── tdatasocket.cpp ├── tdatasocket.h ├── udatasocket.cpp └── udatasocket.h └── README.md /MRoomClient/Config.ini: -------------------------------------------------------------------------------- 1 | IP=192.168.137.1 -------------------------------------------------------------------------------- /MRoomClient/HBScreenShot.cpp: -------------------------------------------------------------------------------- 1 | #include "HBScreenShot.h" 2 | #include 3 | #include "QtWinExtras/qwinfunctions.h" 4 | Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0); 5 | HBScreenShot::HBScreenShot() 6 | { 7 | 8 | } 9 | 10 | 11 | HBScreenShot::~HBScreenShot() 12 | { 13 | } 14 | 15 | QPixmap HBScreenShot::getHBitmap() 16 | { 17 | HWND hWnd = GetDesktopWindow(); //返回桌面窗口句柄 18 | RECT re; //创建一个矩形对象 19 | GetWindowRect(hWnd, &re); //获取窗口大小 20 | 21 | int rWidth = re.right - re.left; //获取窗口的宽 22 | int rHeight = re.bottom - re.top; //获取窗口的长 23 | HDC hScrDC = GetWindowDC(hWnd); //返回hWnd参数所指定的窗口的设备环境 24 | HDC hMemDC = CreateCompatibleDC(hScrDC); //创建一个兼容的内存画板 25 | 26 | HBITMAP hBitmap = CreateCompatibleBitmap(hScrDC, rWidth, rHeight); //该函数用于创建与指定的设备环境相关的设备兼容的位图 27 | HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap); //选中画笔 28 | BitBlt(hMemDC, 0, 0, rWidth, rHeight, hScrDC, 0, 0, SRCCOPY); //绘制图像 29 | 30 | //获取鼠标位置 31 | POINT po; 32 | GetCursorPos(&po); 33 | 34 | //获取鼠标信息,使用GetCursorInfo函数获取光标信息,其中包含图标 35 | CURSORINFO hCur; 36 | ZeroMemory(&hCur, sizeof(hCur)); 37 | hCur.cbSize = sizeof(hCur); 38 | GetCursorInfo(&hCur); 39 | 40 | //添加鼠标图像 41 | HICON hinco = hCur.hCursor; 42 | DrawIcon(hMemDC,po.x - 10, po.y - 10, hinco); 43 | 44 | //恢复原来的画笔 45 | hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap); 46 | return qt_pixmapFromWinHBITMAP(hBitmap); 47 | } 48 | -------------------------------------------------------------------------------- /MRoomClient/HBScreenShot.h: -------------------------------------------------------------------------------- 1 | #include 2 | class HBScreenShot 3 | { 4 | public: 5 | HBScreenShot(); 6 | ~HBScreenShot(); 7 | QPixmap getHBitmap(); 8 | 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /MRoomClient/MRoomClient.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2019-02-27T12:21:55 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | QT += network sql 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = MRoomClient 12 | TEMPLATE = app 13 | # The following define makes your compiler emit warnings if you use 14 | # any feature of Qt which has been marked as deprecated (the exact warnings 15 | # depend on your compiler). Please consult the documentation of the 16 | # deprecated API in order to know how to port your code away from it. 17 | DEFINES += QT_DEPRECATED_WARNINGS 18 | LIBS += -luser32 -lws2_32 -lgdi32 19 | # You can also make your code fail to compile if you use deprecated APIs. 20 | # In order to do so, uncomment the following line. 21 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 22 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 23 | 24 | 25 | SOURCES += \ 26 | main.cpp \ 27 | logindlg.cpp \ 28 | mroomclient.cpp \ 29 | tdatasocket.cpp \ 30 | sfile.cpp \ 31 | udatasocket.cpp \ 32 | HBScreenShot.cpp \ 33 | projectionthread.cpp 34 | 35 | HEADERS += \ 36 | logindlg.h \ 37 | mroomclient.h \ 38 | header.h \ 39 | tdatasocket.h \ 40 | sfile.h \ 41 | udatasocket.h \ 42 | HBScreenShot.h \ 43 | projectionthread.h 44 | 45 | FORMS += \ 46 | logindlg.ui \ 47 | mroomclient.ui \ 48 | sfile.ui 49 | 50 | RESOURCES += \ 51 | resource.qrc 52 | -------------------------------------------------------------------------------- /MRoomClient/MRoomClient.pro.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | EnvironmentId 7 | {fc710196-9f7d-4838-a2ca-b57d1b4804e2} 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 | true 45 | 0 46 | 8 47 | true 48 | 1 49 | true 50 | true 51 | true 52 | false 53 | 54 | 55 | 56 | ProjectExplorer.Project.PluginSettings 57 | 58 | 59 | -fno-delayed-template-parsing 60 | 61 | true 62 | 63 | 64 | 65 | ProjectExplorer.Project.Target.0 66 | 67 | Desktop Qt 5.14.1 MinGW 64-bit 68 | Desktop Qt 5.14.1 MinGW 64-bit 69 | qt.qt5.5141.win64_mingw73_kit 70 | 0 71 | 0 72 | 0 73 | 74 | C:/Users/PC/Desktop/MRoom/MRoomClient/build-MRoomClient-Desktop_Qt_5_14_1_MinGW_64_bit-Debug 75 | 76 | 77 | true 78 | QtProjectManager.QMakeBuildStep 79 | true 80 | 81 | false 82 | false 83 | false 84 | 85 | 86 | true 87 | Qt4ProjectManager.MakeStep 88 | 89 | false 90 | 91 | 92 | false 93 | 94 | 2 95 | Build 96 | Build 97 | ProjectExplorer.BuildSteps.Build 98 | 99 | 100 | 101 | true 102 | Qt4ProjectManager.MakeStep 103 | 104 | true 105 | clean 106 | 107 | false 108 | 109 | 1 110 | Clean 111 | Clean 112 | ProjectExplorer.BuildSteps.Clean 113 | 114 | 2 115 | false 116 | 117 | Debug 118 | Qt4ProjectManager.Qt4BuildConfiguration 119 | 2 120 | 121 | 122 | C:/Users/PC/Desktop/MRoom/MRoomClient/build-MRoomClient-Desktop_Qt_5_14_1_MinGW_64_bit-Release 123 | 124 | 125 | true 126 | QtProjectManager.QMakeBuildStep 127 | false 128 | 129 | false 130 | false 131 | true 132 | 133 | 134 | true 135 | Qt4ProjectManager.MakeStep 136 | 137 | false 138 | 139 | 140 | false 141 | 142 | 2 143 | Build 144 | Build 145 | ProjectExplorer.BuildSteps.Build 146 | 147 | 148 | 149 | true 150 | Qt4ProjectManager.MakeStep 151 | 152 | true 153 | clean 154 | 155 | false 156 | 157 | 1 158 | Clean 159 | Clean 160 | ProjectExplorer.BuildSteps.Clean 161 | 162 | 2 163 | false 164 | 165 | Release 166 | Qt4ProjectManager.Qt4BuildConfiguration 167 | 0 168 | 169 | 170 | C:/Users/PC/Desktop/MRoom/MRoomClient/build-MRoomClient-Desktop_Qt_5_14_1_MinGW_64_bit-Profile 171 | 172 | 173 | true 174 | QtProjectManager.QMakeBuildStep 175 | true 176 | 177 | false 178 | true 179 | true 180 | 181 | 182 | true 183 | Qt4ProjectManager.MakeStep 184 | 185 | false 186 | 187 | 188 | false 189 | 190 | 2 191 | Build 192 | Build 193 | ProjectExplorer.BuildSteps.Build 194 | 195 | 196 | 197 | true 198 | Qt4ProjectManager.MakeStep 199 | 200 | true 201 | clean 202 | 203 | false 204 | 205 | 1 206 | Clean 207 | Clean 208 | ProjectExplorer.BuildSteps.Clean 209 | 210 | 2 211 | false 212 | 213 | Profile 214 | Qt4ProjectManager.Qt4BuildConfiguration 215 | 0 216 | 217 | 3 218 | 219 | 220 | 0 221 | Deploy 222 | Deploy 223 | ProjectExplorer.BuildSteps.Deploy 224 | 225 | 1 226 | ProjectExplorer.DefaultDeployConfiguration 227 | 228 | 1 229 | 230 | 231 | dwarf 232 | 233 | cpu-cycles 234 | 235 | 236 | 250 237 | 238 | -e 239 | cpu-cycles 240 | --call-graph 241 | dwarf,4096 242 | -F 243 | 250 244 | 245 | -F 246 | true 247 | 4096 248 | false 249 | false 250 | 1000 251 | 252 | true 253 | 254 | false 255 | false 256 | false 257 | false 258 | true 259 | 0.01 260 | 10 261 | true 262 | kcachegrind 263 | 1 264 | 25 265 | 266 | 1 267 | true 268 | false 269 | true 270 | valgrind 271 | 272 | 0 273 | 1 274 | 2 275 | 3 276 | 4 277 | 5 278 | 6 279 | 7 280 | 8 281 | 9 282 | 10 283 | 11 284 | 12 285 | 13 286 | 14 287 | 288 | 2 289 | 290 | Qt4ProjectManager.Qt4RunConfiguration:C:/Users/PC/Desktop/MRoom/MRoomClient/MRoomClient/MRoomClient.pro 291 | C:/Users/PC/Desktop/MRoom/MRoomClient/MRoomClient/MRoomClient.pro 292 | 293 | false 294 | 295 | false 296 | true 297 | true 298 | false 299 | false 300 | true 301 | 302 | C:/Users/PC/Desktop/MRoom/MRoomClient/build-MRoomClient-Desktop_Qt_5_14_1_MinGW_64_bit-Debug 303 | 304 | 1 305 | 306 | 307 | 308 | ProjectExplorer.Project.TargetCount 309 | 1 310 | 311 | 312 | ProjectExplorer.Project.Updater.FileVersion 313 | 22 314 | 315 | 316 | Version 317 | 22 318 | 319 | 320 | -------------------------------------------------------------------------------- /MRoomClient/MRoomClient.pro.user.08fac7a: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | EnvironmentId 7 | {08fac7a9-d1d5-4589-bc29-0e31f2e4e17f} 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 | true 45 | 0 46 | 8 47 | true 48 | 1 49 | true 50 | true 51 | true 52 | false 53 | 54 | 55 | 56 | ProjectExplorer.Project.PluginSettings 57 | 58 | 59 | 60 | ProjectExplorer.Project.Target.0 61 | 62 | Desktop Qt 5.10.0 MinGW 32bit 63 | Desktop Qt 5.10.0 MinGW 32bit 64 | qt.qt5.5100.win32_mingw53_kit 65 | 1 66 | 0 67 | 0 68 | 69 | G:/Qt/workspace/MRoomClient/build-MRoomClient-Desktop_Qt_5_10_0_MinGW_32bit-Debug 70 | 71 | 72 | true 73 | qmake 74 | 75 | QtProjectManager.QMakeBuildStep 76 | true 77 | 78 | false 79 | false 80 | false 81 | 82 | 83 | true 84 | Make 85 | 86 | Qt4ProjectManager.MakeStep 87 | 88 | false 89 | 90 | 91 | 92 | 2 93 | 构建 94 | 95 | ProjectExplorer.BuildSteps.Build 96 | 97 | 98 | 99 | true 100 | Make 101 | 102 | Qt4ProjectManager.MakeStep 103 | 104 | true 105 | clean 106 | 107 | 108 | 1 109 | 清理 110 | 111 | ProjectExplorer.BuildSteps.Clean 112 | 113 | 2 114 | false 115 | 116 | Debug 117 | 118 | Qt4ProjectManager.Qt4BuildConfiguration 119 | 2 120 | true 121 | 122 | 123 | G:/Qt/workspace/MRoomClient/build-MRoomClient-Desktop_Qt_5_10_0_MinGW_32bit-Release 124 | 125 | 126 | true 127 | qmake 128 | 129 | QtProjectManager.QMakeBuildStep 130 | false 131 | 132 | false 133 | false 134 | false 135 | 136 | 137 | true 138 | Make 139 | 140 | Qt4ProjectManager.MakeStep 141 | 142 | false 143 | 144 | 145 | 146 | 2 147 | 构建 148 | 149 | ProjectExplorer.BuildSteps.Build 150 | 151 | 152 | 153 | true 154 | Make 155 | 156 | Qt4ProjectManager.MakeStep 157 | 158 | true 159 | clean 160 | 161 | 162 | 1 163 | 清理 164 | 165 | ProjectExplorer.BuildSteps.Clean 166 | 167 | 2 168 | false 169 | 170 | Release 171 | 172 | Qt4ProjectManager.Qt4BuildConfiguration 173 | 0 174 | true 175 | 176 | 177 | G:/Qt/workspace/MRoomClient/build-MRoomClient-Desktop_Qt_5_10_0_MinGW_32bit-Profile 178 | 179 | 180 | true 181 | qmake 182 | 183 | QtProjectManager.QMakeBuildStep 184 | true 185 | 186 | false 187 | true 188 | false 189 | 190 | 191 | true 192 | Make 193 | 194 | Qt4ProjectManager.MakeStep 195 | 196 | false 197 | 198 | 199 | 200 | 2 201 | 构建 202 | 203 | ProjectExplorer.BuildSteps.Build 204 | 205 | 206 | 207 | true 208 | Make 209 | 210 | Qt4ProjectManager.MakeStep 211 | 212 | true 213 | clean 214 | 215 | 216 | 1 217 | 清理 218 | 219 | ProjectExplorer.BuildSteps.Clean 220 | 221 | 2 222 | false 223 | 224 | Profile 225 | 226 | Qt4ProjectManager.Qt4BuildConfiguration 227 | 0 228 | true 229 | 230 | 3 231 | 232 | 233 | 0 234 | 部署 235 | 236 | ProjectExplorer.BuildSteps.Deploy 237 | 238 | 1 239 | 在本地部署 240 | 241 | ProjectExplorer.DefaultDeployConfiguration 242 | 243 | 1 244 | 245 | 246 | false 247 | false 248 | 1000 249 | 250 | true 251 | 252 | false 253 | false 254 | false 255 | false 256 | true 257 | 0.01 258 | 10 259 | true 260 | 1 261 | 25 262 | 263 | 1 264 | true 265 | false 266 | true 267 | valgrind 268 | 269 | 0 270 | 1 271 | 2 272 | 3 273 | 4 274 | 5 275 | 6 276 | 7 277 | 8 278 | 9 279 | 10 280 | 11 281 | 12 282 | 13 283 | 14 284 | 285 | 2 286 | 287 | MRoomClient 288 | 289 | Qt4ProjectManager.Qt4RunConfiguration:G:/Qt/workspace/MRoomClient/MRoomClient/MRoomClient.pro 290 | true 291 | 292 | MRoomClient.pro 293 | false 294 | 295 | G:/Qt/workspace/MRoomClient/build-MRoomClient-Desktop_Qt_5_10_0_MinGW_32bit-Release 296 | 3768 297 | false 298 | true 299 | false 300 | false 301 | true 302 | 303 | 1 304 | 305 | 306 | 307 | ProjectExplorer.Project.TargetCount 308 | 1 309 | 310 | 311 | ProjectExplorer.Project.Updater.FileVersion 312 | 18 313 | 314 | 315 | Version 316 | 18 317 | 318 | 319 | -------------------------------------------------------------------------------- /MRoomClient/MRoomClient.pro.user.25b49aa.4.8-pre1: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | EnvironmentId 7 | {25b49aa2-37ec-4cbf-80dc-6d93e8e3c1b1} 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 | true 45 | 0 46 | 8 47 | true 48 | 1 49 | true 50 | true 51 | true 52 | false 53 | 54 | 55 | 56 | ProjectExplorer.Project.PluginSettings 57 | 58 | 59 | 60 | ProjectExplorer.Project.Target.0 61 | 62 | Desktop Qt 5.10.0 MinGW 32bit 63 | Desktop Qt 5.10.0 MinGW 32bit 64 | qt.qt5.5100.win32_mingw53_kit 65 | 0 66 | 0 67 | 0 68 | 69 | E:/workspace/vs-workspace/MRoomClient/build-MRoomClient-Desktop_Qt_5_10_0_MinGW_32bit-Debug 70 | 71 | 72 | true 73 | qmake 74 | 75 | QtProjectManager.QMakeBuildStep 76 | true 77 | 78 | false 79 | false 80 | false 81 | 82 | 83 | true 84 | Make 85 | 86 | Qt4ProjectManager.MakeStep 87 | 88 | false 89 | 90 | 91 | 92 | 2 93 | Build 94 | 95 | ProjectExplorer.BuildSteps.Build 96 | 97 | 98 | 99 | true 100 | Make 101 | 102 | Qt4ProjectManager.MakeStep 103 | 104 | true 105 | clean 106 | 107 | 108 | 1 109 | Clean 110 | 111 | ProjectExplorer.BuildSteps.Clean 112 | 113 | 2 114 | false 115 | 116 | Debug 117 | Debug 118 | Qt4ProjectManager.Qt4BuildConfiguration 119 | 2 120 | true 121 | 122 | 123 | E:/workspace/vs-workspace/MRoomClient/build-MRoomClient-Desktop_Qt_5_10_0_MinGW_32bit-Release 124 | 125 | 126 | true 127 | qmake 128 | 129 | QtProjectManager.QMakeBuildStep 130 | false 131 | 132 | false 133 | false 134 | false 135 | 136 | 137 | true 138 | Make 139 | 140 | Qt4ProjectManager.MakeStep 141 | 142 | false 143 | 144 | 145 | 146 | 2 147 | Build 148 | 149 | ProjectExplorer.BuildSteps.Build 150 | 151 | 152 | 153 | true 154 | Make 155 | 156 | Qt4ProjectManager.MakeStep 157 | 158 | true 159 | clean 160 | 161 | 162 | 1 163 | Clean 164 | 165 | ProjectExplorer.BuildSteps.Clean 166 | 167 | 2 168 | false 169 | 170 | Release 171 | Release 172 | Qt4ProjectManager.Qt4BuildConfiguration 173 | 0 174 | true 175 | 176 | 177 | E:/workspace/vs-workspace/MRoomClient/build-MRoomClient-Desktop_Qt_5_10_0_MinGW_32bit-Profile 178 | 179 | 180 | true 181 | qmake 182 | 183 | QtProjectManager.QMakeBuildStep 184 | true 185 | 186 | false 187 | true 188 | false 189 | 190 | 191 | true 192 | Make 193 | 194 | Qt4ProjectManager.MakeStep 195 | 196 | false 197 | 198 | 199 | 200 | 2 201 | Build 202 | 203 | ProjectExplorer.BuildSteps.Build 204 | 205 | 206 | 207 | true 208 | Make 209 | 210 | Qt4ProjectManager.MakeStep 211 | 212 | true 213 | clean 214 | 215 | 216 | 1 217 | Clean 218 | 219 | ProjectExplorer.BuildSteps.Clean 220 | 221 | 2 222 | false 223 | 224 | Profile 225 | Profile 226 | Qt4ProjectManager.Qt4BuildConfiguration 227 | 0 228 | true 229 | 230 | 3 231 | 232 | 233 | 0 234 | 部署 235 | 236 | ProjectExplorer.BuildSteps.Deploy 237 | 238 | 1 239 | 部署设置 240 | 241 | ProjectExplorer.DefaultDeployConfiguration 242 | 243 | 1 244 | 245 | 246 | false 247 | false 248 | 1000 249 | 250 | true 251 | 252 | false 253 | false 254 | false 255 | false 256 | true 257 | 0.01 258 | 10 259 | true 260 | 1 261 | 25 262 | 263 | 1 264 | true 265 | false 266 | true 267 | valgrind 268 | 269 | 0 270 | 1 271 | 2 272 | 3 273 | 4 274 | 5 275 | 6 276 | 7 277 | 8 278 | 9 279 | 10 280 | 11 281 | 12 282 | 13 283 | 14 284 | 285 | 2 286 | 287 | MRoomClient 288 | 289 | Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/vs-workspace/MRoomClient/MRoomClient/MRoomClient.pro 290 | true 291 | 292 | MRoomClient.pro 293 | false 294 | 295 | E:/workspace/vs-workspace/MRoomClient/build-MRoomClient-Desktop_Qt_5_10_0_MinGW_32bit-Debug 296 | 3768 297 | false 298 | true 299 | false 300 | false 301 | true 302 | 303 | 1 304 | 305 | 306 | 307 | ProjectExplorer.Project.TargetCount 308 | 1 309 | 310 | 311 | ProjectExplorer.Project.Updater.FileVersion 312 | 18 313 | 314 | 315 | Version 316 | 18 317 | 318 | 319 | -------------------------------------------------------------------------------- /MRoomClient/header.h: -------------------------------------------------------------------------------- 1 | #ifndef HEADER_H 2 | #define HEADER_H 3 | #include 4 | #include 5 | #include 6 | typedef struct tagUserInfo 7 | { 8 | QString userName; 9 | QHostAddress serverIP; 10 | bool chatState; 11 | bool monitorState; 12 | bool projectionState; 13 | QDateTime lastTime; 14 | tagUserInfo() 15 | { 16 | userName = ""; 17 | serverIP = QHostAddress::Null ; 18 | chatState = false; 19 | monitorState = false; 20 | projectionState = false; 21 | } 22 | }UserInfo, *PUserInfo; 23 | 24 | struct ImageFrameHead 25 | { 26 | int funCode; 27 | unsigned int uTransFrameTotalSize; //数据帧总大小 28 | unsigned int uTransFrameCurrSize; //数据现在的大小 29 | 30 | //数据帧变量 31 | unsigned int uDataFrameSize; //文件的大小 32 | unsigned int uDataFrametotal; //数据帧总的个数 33 | unsigned int uDataFrameCurr; //当前第几个帧 34 | unsigned int uDataInFrameOffset; //偏移量 35 | }; 36 | 37 | struct ImageUserInfo //typdef 用新的变量类型去定义新的变量 38 | { 39 | char userName[60]; 40 | unsigned int CMD; 41 | unsigned int dataSize; //头部后面的数据内容的大小 42 | ImageUserInfo() 43 | { 44 | memset(this, 0, sizeof(ImageUserInfo)); 45 | } 46 | }; 47 | 48 | struct Point 49 | { 50 | double x; 51 | double y; 52 | Point() 53 | { 54 | memset(this,0,sizeof(Point)); 55 | } 56 | }; 57 | 58 | #endif // HEADER_H 59 | -------------------------------------------------------------------------------- /MRoomClient/images/resource.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /MRoomClient/images/sysTray.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jennifer249/MultimediaNetClassroom/48ab904fb1bbfb934b668fd53155bc0057a0ba67/MRoomClient/images/sysTray.ico -------------------------------------------------------------------------------- /MRoomClient/logindlg.cpp: -------------------------------------------------------------------------------- 1 | #include "logindlg.h" 2 | #include "ui_logindlg.h" 3 | #include 4 | #include 5 | LoginDlg::LoginDlg(QWidget *parent) : 6 | QDialog(parent), 7 | ui(new Ui::LoginDlg) 8 | { 9 | ui->setupUi(this); 10 | init(); 11 | m = new MRoomClient(); 12 | tempUserName = ""; 13 | } 14 | 15 | LoginDlg::~LoginDlg() 16 | { 17 | delete ui; 18 | } 19 | 20 | void LoginDlg::init() 21 | { 22 | setWindowTitle(tr("局域网多媒体教学软件")); 23 | setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint); 24 | } 25 | 26 | void LoginDlg::paintEvent(QPaintEvent *event) 27 | { 28 | Q_UNUSED(event); 29 | 30 | QPainter p(this); 31 | p.setPen(Qt::NoPen); 32 | p.setBrush(Qt::white); 33 | p.drawRect(rect()); 34 | } 35 | 36 | void LoginDlg::on_loginBtn_clicked() 37 | { 38 | QString inputNames = tr("%1").arg(ui->IDEdit->text()); 39 | m->setLoginNOState(); 40 | if(inputNames.isEmpty()) 41 | { 42 | QMessageBox::warning(0,tr("输入错误"),tr("用户名不得为空"),QMessageBox::Ok); 43 | return; 44 | } 45 | if(inputNames == "Teacher") 46 | { 47 | QMessageBox::warning(0,tr("输入错误"),tr("用户名不得为教师"),QMessageBox::Ok); 48 | return; 49 | } 50 | if(tempUserName == "" || tempUserName != inputNames) 51 | { 52 | qDebug() << tempUserName <setUserName(inputNames)) 54 | { 55 | tempUserName = inputNames; 56 | } 57 | } 58 | else if(tempUserName == inputNames) 59 | QMessageBox::warning(0,tr("登录失败"),tr("该用户名已登录不得重复登录"),QMessageBox::Ok); 60 | connect(m,SIGNAL(loginOK()),this,SLOT(loginOK())); 61 | connect(m,SIGNAL(loginNO()),this,SLOT(loginNO())); 62 | } 63 | 64 | void LoginDlg::on_cancelBtn_clicked() 65 | { 66 | this->close(); 67 | } 68 | 69 | void LoginDlg::loginOK() 70 | { 71 | m->show(); 72 | m->init(); 73 | this->close(); 74 | } 75 | 76 | void LoginDlg::loginNO() 77 | { 78 | m->close(); 79 | QMessageBox::warning(0,tr("登录失败"),tr("该用户名已登录不得重复登录"),QMessageBox::Ok); 80 | qDebug() << "loginON"; 81 | } 82 | -------------------------------------------------------------------------------- /MRoomClient/logindlg.h: -------------------------------------------------------------------------------- 1 | #ifndef LOGINDLG_H 2 | #define LOGINDLG_H 3 | 4 | #include 5 | #include "mroomclient.h" 6 | namespace Ui { 7 | class LoginDlg; 8 | } 9 | 10 | class LoginDlg : public QDialog 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit LoginDlg(QWidget *parent = 0); 16 | ~LoginDlg(); 17 | protected: 18 | void paintEvent(QPaintEvent *event); 19 | private slots: 20 | void on_loginBtn_clicked(); 21 | void on_cancelBtn_clicked(); 22 | void loginOK(); 23 | void loginNO(); 24 | 25 | private: 26 | void init(); 27 | private: 28 | Ui::LoginDlg *ui; 29 | MRoomClient* m; 30 | QString tempUserName; 31 | }; 32 | 33 | #endif // LOGINDLG_H 34 | -------------------------------------------------------------------------------- /MRoomClient/logindlg.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | LoginDlg 4 | 5 | 6 | 7 | 0 8 | 0 9 | 188 10 | 77 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 用户名 24 | 25 | 26 | 27 | 28 | 29 | 30 | 姓名+学号 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 登录 44 | 45 | 46 | 47 | 48 | 49 | 50 | 取消 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /MRoomClient/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "logindlg.h" 3 | int main(int argc, char *argv[]) 4 | { 5 | QApplication a(argc, argv); 6 | QApplication::addLibraryPath("./dll"); 7 | LoginDlg w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /MRoomClient/mroomclient.h: -------------------------------------------------------------------------------- 1 | #ifndef MROOMCLIENT_H 2 | #define MROOMCLIENT_H 3 | 4 | #include 5 | #include 6 | #include "header.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "sfile.h" 14 | #include 15 | #include 16 | #include 17 | #include "udatasocket.h" 18 | #include 19 | #include "HBScreenShot.h" 20 | #include 21 | #include 22 | namespace Ui { 23 | class MRoomClient; 24 | } 25 | 26 | enum MsgType{UserEnter, Msg, UserLeft, PrivateChat, UserList}; 27 | 28 | class MRoomClient : public QDialog 29 | { 30 | Q_OBJECT 31 | 32 | public: 33 | explicit MRoomClient(QWidget *parent = 0); 34 | ~MRoomClient(); 35 | bool setUserName(QString); 36 | void setLoginNOState(); 37 | void init(); //初始化界面 38 | 39 | private: 40 | void connControlPort(); //创建主控连接 41 | void sendConMsg(QString, QHostAddress); //主控端口发送消息 42 | qint64 writeChatMsg(MsgType, QString); //聊天消息发送 43 | void connDataPort(); //连接数据端口 44 | void userEnter(QString); 45 | void userLeft(QString, QString); 46 | void updateMsgTextBrowser(QString, QString, QString); 47 | void sendError(QString); 48 | void sendMsg(MsgType,QString); 49 | void updateUserList(QString); 50 | void showPrivateChat(QString,QString); 51 | void changeUserCount(); 52 | void closeEvent(QCloseEvent *e); 53 | void createProjectionWidget(); //创建教师投影屏幕 54 | void setIP(); 55 | //远程控制 56 | void mousepress(bool LR,int x,int y); 57 | void mousemove(int x,int y); 58 | void mouserelease(bool LR,int x,int y); 59 | void mousedoubleclick(int x, int y); 60 | void keybord(bool PR,int key,QString text); 61 | int translateKeyCode(int key); 62 | 63 | private slots: 64 | void recvConMsg(); //主控端口接收消息 65 | void on_sendBtn_clicked(); 66 | void sendQuit(); 67 | void dealChatMsg(int, QString, QString, QString); 68 | void connectOK(); 69 | void tools(int); 70 | void privateChatChange(int); 71 | void showWindows(); //显示界面 72 | void recvFileOK(); 73 | void showProjection(char*,unsigned int); 74 | void checkHeart(); 75 | void monitor(); 76 | void recvPacket(int); 77 | void remoteControl(); 78 | 79 | private: 80 | Ui::MRoomClient *ui; 81 | quint16 controlPort; 82 | quint16 dataPort; 83 | QUdpSocket *controlSocket; 84 | TDataSocket *tDataSocket; 85 | PUserInfo userInfo; 86 | bool conConnectState; 87 | QTimer* heartTimer; 88 | QNetworkInterface intf; 89 | QString cIP; 90 | //托盘 91 | QSystemTrayIcon *systemTray; 92 | QAction *chatAct; 93 | QAction *quitAct; 94 | QMenu *pContextMenu; 95 | //聊天 96 | bool groupChatState; 97 | int userCount; 98 | bool loginOKState; //判断登录状态,防止多次发送用户列表 99 | bool loginNOState; 100 | SFile* sFile; 101 | //投影 102 | UDataSocket* uDataSocket; 103 | quint16 projectionPort; 104 | QWidget *projectionWidget; 105 | QVBoxLayout *vBoxLayout; 106 | QLabel *projectionLabel; 107 | //监视 108 | HBScreenShot *hBScr; 109 | QTimer *mTimer; 110 | //远程控制 111 | QTimer *rTimer; 112 | QPoint pos; 113 | QCursor mouse; 114 | int winW; 115 | int winH; 116 | 117 | signals: 118 | void loginOK(); 119 | void loginNO(); 120 | }; 121 | 122 | #endif // MROOMCLIENT_H 123 | -------------------------------------------------------------------------------- /MRoomClient/mroomclient.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MRoomClient 4 | 5 | 6 | 7 | 0 8 | 0 9 | 376 10 | 337 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 发送给: 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 所有人 33 | 34 | 35 | 36 | 37 | 教师 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 选择工具: 46 | 47 | 48 | 49 | 50 | 51 | 52 | true 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 文件传输 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 0 73 | 73 74 | 75 | 76 | 77 | 78 | 16777215 79 | 73 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | false 92 | 93 | 94 | false 95 | 96 | 97 | QFrame::Box 98 | 99 | 100 | QFrame::Sunken 101 | 102 | 103 | 在线用户 104 | 105 | 106 | Qt::AlignBottom|Qt::AlignHCenter 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 100 115 | 16777215 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | Qt::Horizontal 128 | 129 | 130 | 131 | 40 132 | 20 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 发送 141 | 142 | 143 | 144 | 145 | 146 | 147 | 关闭 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /MRoomClient/projectionthread.cpp: -------------------------------------------------------------------------------- 1 | #include "projectionthread.h" 2 | #include "header.h" 3 | 4 | ProjectionThread::ProjectionThread(QObject *parent) : QObject(parent) 5 | { 6 | buf = new char[1024*1024]; 7 | memset(buf,0,1024); 8 | pCount = 1; 9 | } 10 | 11 | ProjectionThread::~ProjectionThread() 12 | { 13 | delete buf; 14 | } 15 | 16 | void ProjectionThread::recvProjection(char *imageBuf) 17 | { 18 | qDebug() << "recv ok"; 19 | ImageFrameHead *frame = (ImageFrameHead *)imageBuf; 20 | 21 | qDebug() << "pCount" << pCount << frame->uDataFrameCurr; 22 | if(pCount != (int)frame->uDataFrameCurr) 23 | { 24 | memset(buf, 0, 1024); 25 | pCount = 1; 26 | emit lostPacket(pCount); 27 | return; 28 | } 29 | if(frame->funCode == 0) 30 | { 31 | pCount++; 32 | memcpy(buf+frame->uDataInFrameOffset, (imageBuf+sizeof(ImageFrameHead)), frame->uTransFrameCurrSize); 33 | if(frame->uDataFrameCurr == frame->uDataFrametotal) 34 | { 35 | pCount = 1; 36 | emit recvProjectionOk(buf, frame->uDataFrameSize); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /MRoomClient/projectionthread.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECTIONTHREAD_H 2 | #define PROJECTIONTHREAD_H 3 | #include 4 | class ProjectionThread : public QObject 5 | { 6 | Q_OBJECT 7 | public: 8 | explicit ProjectionThread(QObject *parent = nullptr); 9 | void recvProjection(char* imageBuf); 10 | ~ProjectionThread(); 11 | signals: 12 | void recvProjectionOk(char*, int); 13 | void lostPacket(int); 14 | private: 15 | quint16 monitorPort; 16 | char *buf; 17 | QString userName; 18 | int pCount; 19 | }; 20 | 21 | #endif // PROJECTIONTHREAD_H 22 | -------------------------------------------------------------------------------- /MRoomClient/resource.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | images/sysTray.ico 4 | 5 | 6 | -------------------------------------------------------------------------------- /MRoomClient/sfile.cpp: -------------------------------------------------------------------------------- 1 | #include "sfile.h" 2 | #include "ui_sfile.h" 3 | #include 4 | #include 5 | 6 | SFile::SFile(TDataSocket* tDataSocket,QWidget *parent) : 7 | QDialog(parent), 8 | ui(new Ui::SFile) 9 | { 10 | ui->setupUi(this); 11 | this->tDataSocket = tDataSocket; 12 | connect(ui->closeBtn, SIGNAL(clicked()), this, SLOT(close())); 13 | setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint); 14 | } 15 | 16 | SFile::~SFile() 17 | { 18 | delete ui; 19 | } 20 | 21 | void SFile::on_openBtn_clicked() 22 | { 23 | filePath = QFileDialog::getOpenFileName(this); 24 | if(!filePath.isEmpty()) 25 | { 26 | fileName = filePath.right(filePath.size()-filePath.lastIndexOf('/')-1); //匹配从右边开始的子项 27 | ui->msgLabel->setText(tr("要传送的文件为:%1").arg(fileName)); 28 | ui->sendBtn->setEnabled(true); 29 | ui->openBtn->setEnabled(false); 30 | } 31 | } 32 | 33 | void SFile::on_sendBtn_clicked() 34 | { 35 | writtenSum = 0; 36 | ui->msgLabel->setText(tr("准备发送文件 %1 ").arg(fileName)); 37 | ui->sendBtn->setEnabled(false); 38 | tDataSocket->writeFile(filePath); 39 | connect(tDataSocket, SIGNAL(fileWarning(QString)),this, SLOT(fileWarning(QString))); 40 | connect(tDataSocket, SIGNAL(updateProgressBar(qint64,qint64,QString)),this,SLOT(updateProgressBar(qint64,qint64,QString))); 41 | } 42 | 43 | void SFile::fileWarning(QString error) 44 | { 45 | QMessageBox::warning(this, tr("应用程序"), tr("无法读取文件 %1:\n%2").arg(fileName).arg(error)); 46 | } 47 | 48 | void SFile::updateProgressBar(qint64 totalBytes, qint64 bytesWritten, QString msg) 49 | { 50 | ui->progressBar->setMaximum(totalBytes); 51 | ui->progressBar->setValue(bytesWritten); 52 | ui->msgLabel->setText(msg); 53 | qDebug() << "updateProgressBar" << bytesWritten << totalBytes; 54 | if(bytesWritten == totalBytes) 55 | { 56 | ui->msgLabel->setText(tr("传送文件%1成功").arg(fileName)); 57 | bytesWritten = 0; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /MRoomClient/sfile.h: -------------------------------------------------------------------------------- 1 | #ifndef SFILE_H 2 | #define SFILE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "tdatasocket.h" 8 | namespace Ui { 9 | class SFile; 10 | } 11 | 12 | class SFile : public QDialog 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit SFile(TDataSocket*, QWidget *parent = 0); 18 | ~SFile(); 19 | 20 | private slots: 21 | void on_openBtn_clicked(); 22 | void on_sendBtn_clicked(); 23 | void fileWarning(QString); 24 | void updateProgressBar(qint64,qint64,QString); 25 | 26 | private: 27 | Ui::SFile *ui; 28 | QString filePath; 29 | QString fileName; 30 | TDataSocket* tDataSocket; 31 | 32 | qint64 totalBytes; //总共 33 | qint64 bytesWritten; //已经写的 34 | qint64 bytesTobeWrite; //剩下的 35 | qint64 payloadSize; 36 | QTime time; 37 | qint64 writtenSum; 38 | }; 39 | 40 | #endif // SFILE_H 41 | -------------------------------------------------------------------------------- /MRoomClient/sfile.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | SFile 4 | 5 | 6 | 7 | 0 8 | 0 9 | 248 10 | 124 11 | 12 | 13 | 14 | 文件传输 15 | 16 | 17 | 18 | 19 | 20 | 选择文件/文件夹 21 | 22 | 23 | 24 | 25 | 26 | 27 | 打开... 28 | 29 | 30 | 31 | 32 | 33 | 34 | 发送 35 | 36 | 37 | 38 | 39 | 40 | 41 | 0 42 | 43 | 44 | 45 | 46 | 47 | 48 | 关闭 49 | 50 | 51 | 52 | 53 | 54 | 55 | 请选择要发送的文件! 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /MRoomClient/tdatasocket.cpp: -------------------------------------------------------------------------------- 1 | #include "tdatasocket.h" 2 | TDataSocket::TDataSocket(QHostAddress serIP, quint16 dataPort, QObject *parent) : QTcpSocket(parent) 3 | { 4 | this->connectToHost(serIP, dataPort); 5 | connect(this, SIGNAL(readyRead()),this,SLOT(recvTDataMsg())); 6 | connect(this,SIGNAL(bytesWritten(qint64)),this,SLOT(continueSend(qint64))); 7 | 8 | fileState = false; 9 | payloadSize = 64*1024; 10 | totalBytes = 0; 11 | bytesWritten = 0; 12 | bytesTobeWrite = 0; 13 | 14 | recvTotalBytes = 0; 15 | bytesReceived = 0; 16 | fileNameSize = 0; 17 | blockSize = 0; 18 | } 19 | 20 | void TDataSocket::recvTDataMsg() 21 | { 22 | if(this->bytesAvailable() <= 0) 23 | return; 24 | 25 | //临时读取缓冲区的所有数据 26 | QByteArray tempBuffer; 27 | tempBuffer = this->readAll(); 28 | //上次缓冲加上这次的数据 29 | tPendingBuffer.append(tempBuffer); 30 | ushort CMD; 31 | 32 | pendingDataSize = tPendingBuffer.size(); 33 | while(pendingDataSize) 34 | { 35 | QDataStream in(tPendingBuffer); 36 | in.setByteOrder(QDataStream::BigEndian); 37 | 38 | //不够包头的数据不处理 39 | if(pendingDataSize < (int)sizeof(ushort)) 40 | break; 41 | 42 | in >> CMD; 43 | 44 | qDebug() <> len; 51 | if(pendingDataSize < (int)len) 52 | break; 53 | int type; 54 | QString msg = NULL; 55 | QString time; 56 | QString userName; 57 | in >> type >> userName >> msg >> time; 58 | // qDebug() << type << userName << msg << time; 59 | emit dealChatMsg(type, userName, msg, time); 60 | //总的数据,前面部分已处理,将后面部分缓存 61 | tempBuffer = tPendingBuffer.right(pendingDataSize - len); 62 | //更新长度 63 | pendingDataSize = tempBuffer.size(); 64 | //更新待处理的数据 65 | tPendingBuffer = tempBuffer; 66 | } 67 | else if(CMD == (ushort)1) 68 | { 69 | if (bytesReceived <= sizeof(qint64)*2+(int)sizeof(ushort)) //先获得前两个数据,文件的大小、文件名的大小 70 | { 71 | if ((pendingDataSize >= (int)sizeof(qint64)*2+(int)sizeof(ushort)) && (fileNameSize == 0)) 72 | { 73 | in >> recvTotalBytes >> fileNameSize; //获得文件的大小、文件名的大小 74 | bytesReceived += sizeof(qint64)*2+(int)sizeof(ushort); 75 | pendingDataSize -= (int)sizeof(qint64)*2+(int)sizeof(ushort); 76 | } 77 | if((pendingDataSize >= fileNameSize) && (fileNameSize != 0)){ //获取文件名 78 | in >> fileName; 79 | bytesReceived += fileNameSize; 80 | pendingDataSize -= fileNameSize; 81 | } 82 | else 83 | { 84 | updatePending(bytesReceived); 85 | //数据不足等下次 86 | return; 87 | } 88 | updatePending(bytesReceived); 89 | } 90 | if(!fileName.isEmpty() && locFile == Q_NULLPTR) 91 | { 92 | locFile = new QFile(fileName); 93 | if(!locFile->open(QFile::WriteOnly)) 94 | { 95 | qDebug()<< "File Open Failed"; 96 | delete locFile; 97 | locFile = Q_NULLPTR; 98 | return; 99 | } 100 | } 101 | 102 | if(locFile == Q_NULLPTR) 103 | return; 104 | 105 | int writeMin = qMin(pendingDataSize-(int)sizeof(ushort), (int)(recvTotalBytes-bytesReceived)); 106 | if (bytesReceived < recvTotalBytes) { 107 | bytesReceived += writeMin; 108 | qDebug() << "writeMin" << writeMin; 109 | locFile->write(tPendingBuffer.right(pendingDataSize-(int)sizeof(ushort)), writeMin); 110 | updatePending(writeMin+(int)sizeof(ushort)); 111 | } 112 | 113 | if(bytesReceived == recvTotalBytes) 114 | { 115 | locFile->close(); 116 | locFile = Q_NULLPTR; 117 | fileName = ""; 118 | recvTotalBytes = 0; 119 | bytesReceived = 0; 120 | fileNameSize = 0; 121 | blockSize = 0; 122 | tempBuffer = tPendingBuffer.right(pendingDataSize-(int)sizeof(ushort)); 123 | //更新长度 124 | pendingDataSize = tempBuffer.size(); 125 | //更新待处理的数据 126 | tPendingBuffer = tempBuffer; 127 | qDebug() << pendingDataSize; 128 | emit recvFileOK(); 129 | } 130 | return; 131 | } 132 | } 133 | } 134 | 135 | void TDataSocket::setUserName(QString userName) 136 | { 137 | this->userName = userName; 138 | } 139 | 140 | QString TDataSocket::getUserName() 141 | { 142 | return userName; 143 | } 144 | 145 | //更新缓冲区数据 146 | void TDataSocket::updatePending(int len) 147 | { 148 | QByteArray temp; 149 | QDataStream out(&temp,QIODevice::WriteOnly); 150 | out << (ushort)1; 151 | //总的数据,前面部分已处理,将后面部分缓存 152 | temp.append(tPendingBuffer.right(tPendingBuffer.size()-len)); 153 | //更新长度 154 | pendingDataSize = temp.size(); 155 | //更新待处理的数据 156 | tPendingBuffer = temp; 157 | } 158 | 159 | //发送文件 160 | void TDataSocket::writeFile(QString filePath) 161 | { 162 | fileState = true; 163 | localFile = new QFile(filePath); 164 | if(!localFile->open(QFile::ReadOnly)) 165 | { 166 | emit fileWarning(localFile->errorString()); 167 | return; 168 | } 169 | totalBytes = localFile->size(); //文件大小 170 | 171 | qDebug() << "totalBytes" <seek(0); 179 | ushort CMD = (ushort)1; //文件 180 | out << CMD << totalBytes << qint64(fileBlock.size()-sizeof(qint64)*2-sizeof(ushort)); //写入总文件大小,文件名大小 181 | qDebug() << CMD << totalBytes << qint64(fileBlock.size()-sizeof(qint64)*2-sizeof(ushort)); 182 | bytesTobeWrite = totalBytes - write(fileBlock); //发送首部后,计算剩余大小 183 | fileBlock.resize(0); 184 | } 185 | 186 | void TDataSocket::continueSend(qint64 numBytes) 187 | { 188 | if(fileState == false) 189 | return; 190 | bytesWritten += (int)numBytes; 191 | sendProgressMsg(); 192 | if(bytesTobeWrite > 0) 193 | { 194 | fileBlock = localFile->read(qMin(bytesTobeWrite,payloadSize)); //读取该大小的数据 195 | bytesTobeWrite -= (int)write(fileBlock); //写入 196 | qDebug() << "bytesTobeWrite" <isOpen()) 201 | localFile->close(); 202 | fileBlock.resize(0); 203 | fileState = false; 204 | totalBytes = 0; 205 | bytesWritten = 0; 206 | bytesTobeWrite = 0; 207 | } 208 | 209 | if(bytesWritten == totalBytes) 210 | { 211 | if(localFile->isOpen()) 212 | localFile->close(); 213 | fileBlock.resize(0); 214 | fileState = false; 215 | totalBytes = 0; 216 | bytesWritten = 0; 217 | bytesTobeWrite = 0; 218 | } 219 | } 220 | 221 | void TDataSocket::sendProgressMsg() 222 | { 223 | float useTime = time.elapsed(); 224 | double speed = bytesWritten / useTime; 225 | QString msg = tr("已发送%1MB(%2MB/s \n共%3MB 已用时:%4秒\n估计剩余时间:%5s)") 226 | .arg((double)bytesWritten/(1024*1024),0,'f',2) 227 | .arg(speed*1000/(1024*1024),0,'f',2) 228 | .arg((double)totalBytes/(1024*1024),0,'f',2) 229 | .arg(useTime/1000,0,'f',0) 230 | .arg((double)totalBytes/speed/1000 - useTime/1000,0,'f',0); 231 | emit updateProgressBar(totalBytes,bytesWritten,msg); 232 | } 233 | 234 | -------------------------------------------------------------------------------- /MRoomClient/tdatasocket.h: -------------------------------------------------------------------------------- 1 | #ifndef TDATASOCKET_H 2 | #define TDATASOCKET_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | class TDataSocket : public QTcpSocket 10 | { 11 | Q_OBJECT 12 | public: 13 | explicit TDataSocket(QHostAddress serIP, quint16 dataPort, QObject *parent = nullptr); 14 | void setUserName(QString); 15 | QString getUserName(); 16 | void writeFile(QString); 17 | private: 18 | void updatePending(int); 19 | void sendProgressMsg(); 20 | private slots: 21 | void continueSend(qint64); 22 | private: 23 | //tcp沾包处理 24 | QByteArray tRecvData; 25 | qint64 tDataSize; 26 | qint64 tCheckSize; 27 | QByteArray tPendingBuffer; 28 | QString userName; 29 | int socketDescriptor; 30 | //写文件 31 | QFile* localFile; 32 | qint64 totalBytes; //总共 33 | qint64 bytesWritten; //已经写的 34 | qint64 bytesTobeWrite; //剩下的 35 | qint64 payloadSize; 36 | QTime time; 37 | QByteArray fileBlock; 38 | bool fileState; 39 | //接收文件 40 | qint64 recvTotalBytes; 41 | qint64 bytesReceived; 42 | qint64 fileNameSize; 43 | QString fileName; 44 | QFile *locFile = Q_NULLPTR; 45 | quint16 blockSize; 46 | int pendingDataSize; 47 | signals: 48 | void dealChatMsg(int, QString, QString, QString); 49 | void recvFileOK(); 50 | void fileWarning(QString); 51 | void updateProgressBar(qint64,qint64,QString); 52 | 53 | public slots: 54 | void recvTDataMsg(); 55 | }; 56 | 57 | #endif // TDATASOCKET_H 58 | -------------------------------------------------------------------------------- /MRoomClient/udatasocket.cpp: -------------------------------------------------------------------------------- 1 | #include "udatasocket.h" 2 | #include "header.h" 3 | #include 4 | UDataSocket::UDataSocket(quint16 port, QNetworkInterface intf, QString cIP, QObject *parent) 5 | :QThread(parent) 6 | { 7 | buf = new char[1024*1024*100]; 8 | memset(buf, 0, 1024); 9 | dataPort = port; 10 | pCount = 1; 11 | this->intf = intf; 12 | this->cIP = cIP; 13 | lastCount = 0; 14 | } 15 | 16 | UDataSocket::~UDataSocket() 17 | { 18 | uDataSocket->close(); 19 | delete buf; 20 | } 21 | 22 | void UDataSocket::run() 23 | { 24 | // QThread thread; 25 | // projectionThread = new ProjectionThread(); 26 | // projectionThread->moveToThread(&thread); 27 | 28 | // connect(projectionThread, SIGNAL(recvProjectionOk(char*,int)), this, SIGNAL(recvProjectionOk(char*,int)),Qt::DirectConnection); 29 | // connect(projectionThread, SIGNAL(lostPacket(int)), this, SIGNAL(lostPacket(int)),Qt::DirectConnection); 30 | 31 | uDataSocket = new QUdpSocket; 32 | if(!uDataSocket->bind(QHostAddress(cIP), dataPort,QUdpSocket::ShareAddress|QUdpSocket::ReuseAddressHint)) 33 | qDebug()<<"bind failed--"; 34 | if(!uDataSocket->joinMulticastGroup(QHostAddress("224.2.2.3"))) 35 | qDebug()<<"joinMuticastGroup failed--"; 36 | uDataSocket->setSocketOption(QAbstractSocket::ReceiveBufferSizeSocketOption,1024*1024*64); 37 | uDataSocket->setMulticastInterface(intf); 38 | 39 | connect(uDataSocket,SIGNAL(readyRead()),this,SLOT(recvProjection()),Qt::DirectConnection); 40 | exec(); 41 | } 42 | 43 | void UDataSocket::leaveMGroup() 44 | { 45 | uDataSocket->leaveMulticastGroup(QHostAddress("224.2.2.3"), intf); 46 | } 47 | 48 | void UDataSocket::recvProjection() 49 | { 50 | char *recvBuf = new char[1052]; 51 | memset(recvBuf, 0, 1052); 52 | while(uDataSocket->hasPendingDatagrams()) 53 | { 54 | memset(recvBuf,0,1052); 55 | int fileSize = uDataSocket->pendingDatagramSize(); 56 | // qDebug() << "fileSize:" << fileSize; 57 | 58 | uDataSocket->readDatagram(recvBuf, fileSize); 59 | ImageFrameHead *frame = (ImageFrameHead *)recvBuf; 60 | 61 | qDebug() << "pCount" << pCount << frame->uDataFrameCurr; 62 | 63 | if(pCount != (int)frame->uDataFrameCurr) //丢包 64 | { 65 | memset(buf, 0, 1024*1024); 66 | pCount = 1; 67 | continue; 68 | } 69 | if(frame->funCode == 0) 70 | { 71 | pCount++; 72 | memcpy(buf+frame->uDataInFrameOffset, (recvBuf+sizeof(ImageFrameHead)), frame->uTransFrameCurrSize); 73 | qDebug() <<"curr"<uDataFrameCurr << frame->uDataFrametotal; 74 | if(frame->uDataFrameCurr == frame->uDataFrametotal) 75 | { 76 | pCount = 1; 77 | emit recvProjectionOk(buf, frame->uDataFrameSize); 78 | } 79 | } 80 | } 81 | delete recvBuf; 82 | } 83 | 84 | qint64 UDataSocket::write(char *data, qint64 size, QHostAddress address) 85 | { 86 | return uDataSocket->writeDatagram(data,size,address,dataPort); 87 | } 88 | -------------------------------------------------------------------------------- /MRoomClient/udatasocket.h: -------------------------------------------------------------------------------- 1 | #ifndef UDATASOCKET_H 2 | #define UDATASOCKET_H 3 | 4 | #include 5 | #include 6 | #include 7 | //#include "projectionthread.h" 8 | class UDataSocket : public QThread 9 | { 10 | Q_OBJECT 11 | public: 12 | UDataSocket(quint16 port, QNetworkInterface intf, QString cIP, QObject* parent = 0); 13 | ~UDataSocket(); 14 | qint64 write(char*, qint64, QHostAddress); 15 | void leaveMGroup(); 16 | 17 | protected: 18 | virtual void run(); 19 | 20 | public slots: 21 | void recvProjection(); 22 | 23 | signals: 24 | void recvProjectionOk(char*,unsigned int); 25 | void recvPacket(int); 26 | private: 27 | QUdpSocket* uDataSocket; 28 | quint16 dataPort; 29 | char *buf; 30 | int pCount; 31 | QNetworkInterface intf; 32 | // ProjectionThread *projectionThread; 33 | QString cIP; 34 | int lastCount; 35 | }; 36 | 37 | #endif // UDATASOCKET_H 38 | -------------------------------------------------------------------------------- /MRoomServer/Config.ini: -------------------------------------------------------------------------------- 1 | IP=192.168.43.129 -------------------------------------------------------------------------------- /MRoomServer/HBScreenShot.cpp: -------------------------------------------------------------------------------- 1 | #include "HBScreenShot.h" 2 | #include 3 | #include "QtWinExtras/qwinfunctions.h" 4 | Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0); 5 | HBScreenShot::HBScreenShot() 6 | { 7 | 8 | } 9 | 10 | 11 | HBScreenShot::~HBScreenShot() 12 | { 13 | } 14 | 15 | QPixmap HBScreenShot::getHBitmap() 16 | { 17 | HWND hWnd = GetDesktopWindow(); //返回桌面窗口句柄 18 | RECT re; //创建一个矩形对象 19 | GetWindowRect(hWnd, &re); //获取窗口大小 20 | 21 | int rWidth = re.right - re.left; //获取窗口的宽 22 | int rHeight = re.bottom - re.top; //获取窗口的长 23 | HDC hScrDC = GetWindowDC(hWnd); //返回hWnd参数所指定的窗口的设备环境 24 | HDC hMemDC = CreateCompatibleDC(hScrDC); //创建一个兼容的内存画板 25 | 26 | HBITMAP hBitmap = CreateCompatibleBitmap(hScrDC, rWidth, rHeight); //该函数用于创建与指定的设备环境相关的设备兼容的位图 27 | HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap); //选中画笔 28 | BitBlt(hMemDC, 0, 0, rWidth, rHeight, hScrDC, 0, 0, SRCCOPY); //绘制图像 29 | 30 | //获取鼠标位置 31 | POINT po; 32 | GetCursorPos(&po); 33 | 34 | //获取鼠标信息,使用GetCursorInfo函数获取光标信息,其中包含图标 35 | CURSORINFO hCur; 36 | ZeroMemory(&hCur, sizeof(hCur)); 37 | hCur.cbSize = sizeof(hCur); 38 | GetCursorInfo(&hCur); 39 | 40 | //添加鼠标图像 41 | HICON hinco = hCur.hCursor; 42 | DrawIcon(hMemDC,po.x - 10, po.y - 10, hinco); 43 | 44 | //恢复原来的画笔 45 | hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap); 46 | return qt_pixmapFromWinHBITMAP(hBitmap); 47 | } 48 | -------------------------------------------------------------------------------- /MRoomServer/HBScreenShot.h: -------------------------------------------------------------------------------- 1 | #include 2 | class HBScreenShot 3 | { 4 | public: 5 | HBScreenShot(); 6 | ~HBScreenShot(); 7 | QPixmap getHBitmap(); 8 | }; 9 | 10 | -------------------------------------------------------------------------------- /MRoomServer/MRoomServer.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2019-02-26T21:46:02 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | QT += network 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = MRoomServer 12 | TEMPLATE = app 13 | # The following define makes your compiler emit warnings if you use 14 | # any feature of Qt which has been marked as deprecated (the exact warnings 15 | # depend on your compiler). Please consult the documentation of the 16 | # deprecated API in order to know how to port your code away from it. 17 | DEFINES += QT_DEPRECATED_WARNINGS 18 | LIBS += -luser32 -lws2_32 -lgdi32 19 | # You can also make your code fail to compile if you use deprecated APIs. 20 | # In order to do so, uncomment the following line. 21 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 22 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 23 | 24 | 25 | SOURCES += \ 26 | main.cpp \ 27 | mroomserver.cpp \ 28 | logindlg.cpp \ 29 | tdatasocket.cpp \ 30 | sfile.cpp \ 31 | HBScreenShot.cpp \ 32 | monitorthread.cpp \ 33 | udatasocket.cpp \ 34 | remotecontroldlg.cpp 35 | 36 | HEADERS += \ 37 | mroomserver.h \ 38 | header.h \ 39 | logindlg.h \ 40 | tdatasocket.h \ 41 | sfile.h \ 42 | HBScreenShot.h \ 43 | monitorthread.h \ 44 | udatasocket.h \ 45 | remotecontroldlg.h 46 | 47 | FORMS += \ 48 | mroomserver.ui \ 49 | logindlg.ui \ 50 | sfile.ui \ 51 | remotecontroldlg.ui 52 | 53 | RESOURCES += \ 54 | resource.qrc 55 | -------------------------------------------------------------------------------- /MRoomServer/MRoomServer.pro.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | EnvironmentId 7 | {fc710196-9f7d-4838-a2ca-b57d1b4804e2} 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 | true 45 | 0 46 | 8 47 | true 48 | 1 49 | true 50 | true 51 | true 52 | false 53 | 54 | 55 | 56 | ProjectExplorer.Project.PluginSettings 57 | 58 | 59 | -fno-delayed-template-parsing 60 | 61 | true 62 | 63 | 64 | 65 | ProjectExplorer.Project.Target.0 66 | 67 | Desktop Qt 5.14.1 MinGW 64-bit 68 | Desktop Qt 5.14.1 MinGW 64-bit 69 | qt.qt5.5141.win64_mingw73_kit 70 | 0 71 | 0 72 | 0 73 | 74 | C:/Users/PC/Desktop/MRoom/MRoomServer/build-MRoomServer-Desktop_Qt_5_14_1_MinGW_64_bit-Debug 75 | 76 | 77 | true 78 | QtProjectManager.QMakeBuildStep 79 | true 80 | 81 | false 82 | false 83 | false 84 | 85 | 86 | true 87 | Qt4ProjectManager.MakeStep 88 | 89 | false 90 | 91 | 92 | false 93 | 94 | 2 95 | Build 96 | Build 97 | ProjectExplorer.BuildSteps.Build 98 | 99 | 100 | 101 | true 102 | Qt4ProjectManager.MakeStep 103 | 104 | true 105 | clean 106 | 107 | false 108 | 109 | 1 110 | Clean 111 | Clean 112 | ProjectExplorer.BuildSteps.Clean 113 | 114 | 2 115 | false 116 | 117 | Debug 118 | Qt4ProjectManager.Qt4BuildConfiguration 119 | 2 120 | 121 | 122 | C:/Users/PC/Desktop/MRoom/MRoomServer/build-MRoomServer-Desktop_Qt_5_14_1_MinGW_64_bit-Release 123 | 124 | 125 | true 126 | QtProjectManager.QMakeBuildStep 127 | false 128 | 129 | false 130 | false 131 | true 132 | 133 | 134 | true 135 | Qt4ProjectManager.MakeStep 136 | 137 | false 138 | 139 | 140 | false 141 | 142 | 2 143 | Build 144 | Build 145 | ProjectExplorer.BuildSteps.Build 146 | 147 | 148 | 149 | true 150 | Qt4ProjectManager.MakeStep 151 | 152 | true 153 | clean 154 | 155 | false 156 | 157 | 1 158 | Clean 159 | Clean 160 | ProjectExplorer.BuildSteps.Clean 161 | 162 | 2 163 | false 164 | 165 | Release 166 | Qt4ProjectManager.Qt4BuildConfiguration 167 | 0 168 | 169 | 170 | C:/Users/PC/Desktop/MRoom/MRoomServer/build-MRoomServer-Desktop_Qt_5_14_1_MinGW_64_bit-Profile 171 | 172 | 173 | true 174 | QtProjectManager.QMakeBuildStep 175 | true 176 | 177 | false 178 | true 179 | true 180 | 181 | 182 | true 183 | Qt4ProjectManager.MakeStep 184 | 185 | false 186 | 187 | 188 | false 189 | 190 | 2 191 | Build 192 | Build 193 | ProjectExplorer.BuildSteps.Build 194 | 195 | 196 | 197 | true 198 | Qt4ProjectManager.MakeStep 199 | 200 | true 201 | clean 202 | 203 | false 204 | 205 | 1 206 | Clean 207 | Clean 208 | ProjectExplorer.BuildSteps.Clean 209 | 210 | 2 211 | false 212 | 213 | Profile 214 | Qt4ProjectManager.Qt4BuildConfiguration 215 | 0 216 | 217 | 3 218 | 219 | 220 | 0 221 | Deploy 222 | Deploy 223 | ProjectExplorer.BuildSteps.Deploy 224 | 225 | 1 226 | ProjectExplorer.DefaultDeployConfiguration 227 | 228 | 1 229 | 230 | 231 | dwarf 232 | 233 | cpu-cycles 234 | 235 | 236 | 250 237 | 238 | -e 239 | cpu-cycles 240 | --call-graph 241 | dwarf,4096 242 | -F 243 | 250 244 | 245 | -F 246 | true 247 | 4096 248 | false 249 | false 250 | 1000 251 | 252 | true 253 | 254 | false 255 | false 256 | false 257 | false 258 | true 259 | 0.01 260 | 10 261 | true 262 | kcachegrind 263 | 1 264 | 25 265 | 266 | 1 267 | true 268 | false 269 | true 270 | valgrind 271 | 272 | 0 273 | 1 274 | 2 275 | 3 276 | 4 277 | 5 278 | 6 279 | 7 280 | 8 281 | 9 282 | 10 283 | 11 284 | 12 285 | 13 286 | 14 287 | 288 | 2 289 | 290 | Qt4ProjectManager.Qt4RunConfiguration:C:/Users/PC/Desktop/MRoom/MRoomServer/MRoomServer/MRoomServer.pro 291 | C:/Users/PC/Desktop/MRoom/MRoomServer/MRoomServer/MRoomServer.pro 292 | 293 | false 294 | 295 | false 296 | true 297 | true 298 | false 299 | false 300 | true 301 | 302 | C:/Users/PC/Desktop/MRoom/MRoomServer/build-MRoomServer-Desktop_Qt_5_14_1_MinGW_64_bit-Debug 303 | 304 | 1 305 | 306 | 307 | 308 | ProjectExplorer.Project.TargetCount 309 | 1 310 | 311 | 312 | ProjectExplorer.Project.Updater.FileVersion 313 | 22 314 | 315 | 316 | Version 317 | 22 318 | 319 | 320 | -------------------------------------------------------------------------------- /MRoomServer/MRoomServer.pro.user.25b49aa.4.8-pre1: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | EnvironmentId 7 | {25b49aa2-37ec-4cbf-80dc-6d93e8e3c1b1} 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 | true 45 | 0 46 | 8 47 | true 48 | 1 49 | true 50 | true 51 | true 52 | false 53 | 54 | 55 | 56 | ProjectExplorer.Project.PluginSettings 57 | 58 | 59 | 60 | ProjectExplorer.Project.Target.0 61 | 62 | Desktop Qt 5.10.0 MinGW 32bit 63 | Desktop Qt 5.10.0 MinGW 32bit 64 | qt.qt5.5100.win32_mingw53_kit 65 | 1 66 | 0 67 | 0 68 | 69 | E:/workspace/vs-workspace/MRoomServer/build-MRoomServer-Desktop_Qt_5_10_0_MinGW_32bit-Debug 70 | 71 | 72 | true 73 | qmake 74 | 75 | QtProjectManager.QMakeBuildStep 76 | true 77 | 78 | false 79 | false 80 | false 81 | 82 | 83 | true 84 | Make 85 | 86 | Qt4ProjectManager.MakeStep 87 | 88 | false 89 | 90 | 91 | 92 | 2 93 | Build 94 | 95 | ProjectExplorer.BuildSteps.Build 96 | 97 | 98 | 99 | true 100 | Make 101 | 102 | Qt4ProjectManager.MakeStep 103 | 104 | true 105 | clean 106 | 107 | 108 | 1 109 | Clean 110 | 111 | ProjectExplorer.BuildSteps.Clean 112 | 113 | 2 114 | false 115 | 116 | Debug 117 | Debug 118 | Qt4ProjectManager.Qt4BuildConfiguration 119 | 2 120 | true 121 | 122 | 123 | E:/workspace/vs-workspace/MRoomServer/build-MRoomServer-Desktop_Qt_5_10_0_MinGW_32bit-Release 124 | 125 | 126 | true 127 | qmake 128 | 129 | QtProjectManager.QMakeBuildStep 130 | false 131 | 132 | false 133 | false 134 | false 135 | 136 | 137 | true 138 | Make 139 | 140 | Qt4ProjectManager.MakeStep 141 | 142 | false 143 | 144 | 145 | 146 | 2 147 | Build 148 | 149 | ProjectExplorer.BuildSteps.Build 150 | 151 | 152 | 153 | true 154 | Make 155 | 156 | Qt4ProjectManager.MakeStep 157 | 158 | true 159 | clean 160 | 161 | 162 | 1 163 | Clean 164 | 165 | ProjectExplorer.BuildSteps.Clean 166 | 167 | 2 168 | false 169 | 170 | Release 171 | Release 172 | Qt4ProjectManager.Qt4BuildConfiguration 173 | 0 174 | true 175 | 176 | 177 | E:/workspace/vs-workspace/MRoomServer/build-MRoomServer-Desktop_Qt_5_10_0_MinGW_32bit-Profile 178 | 179 | 180 | true 181 | qmake 182 | 183 | QtProjectManager.QMakeBuildStep 184 | true 185 | 186 | false 187 | true 188 | false 189 | 190 | 191 | true 192 | Make 193 | 194 | Qt4ProjectManager.MakeStep 195 | 196 | false 197 | 198 | 199 | 200 | 2 201 | Build 202 | 203 | ProjectExplorer.BuildSteps.Build 204 | 205 | 206 | 207 | true 208 | Make 209 | 210 | Qt4ProjectManager.MakeStep 211 | 212 | true 213 | clean 214 | 215 | 216 | 1 217 | Clean 218 | 219 | ProjectExplorer.BuildSteps.Clean 220 | 221 | 2 222 | false 223 | 224 | Profile 225 | Profile 226 | Qt4ProjectManager.Qt4BuildConfiguration 227 | 0 228 | true 229 | 230 | 3 231 | 232 | 233 | 0 234 | 部署 235 | 236 | ProjectExplorer.BuildSteps.Deploy 237 | 238 | 1 239 | 部署设置 240 | 241 | ProjectExplorer.DefaultDeployConfiguration 242 | 243 | 1 244 | 245 | 246 | false 247 | false 248 | 1000 249 | 250 | true 251 | 252 | false 253 | false 254 | false 255 | false 256 | true 257 | 0.01 258 | 10 259 | true 260 | 1 261 | 25 262 | 263 | 1 264 | true 265 | false 266 | true 267 | valgrind 268 | 269 | 0 270 | 1 271 | 2 272 | 3 273 | 4 274 | 5 275 | 6 276 | 7 277 | 8 278 | 9 279 | 10 280 | 11 281 | 12 282 | 13 283 | 14 284 | 285 | 2 286 | 287 | MRoomServer 288 | 289 | Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/vs-workspace/MRoomServer/MRoomServer/MRoomServer.pro 290 | true 291 | 292 | MRoomServer.pro 293 | false 294 | 295 | E:/workspace/vs-workspace/MRoomServer/build-MRoomServer-Desktop_Qt_5_10_0_MinGW_32bit-Release 296 | 3768 297 | false 298 | true 299 | false 300 | false 301 | true 302 | 303 | 1 304 | 305 | 306 | 307 | ProjectExplorer.Project.TargetCount 308 | 1 309 | 310 | 311 | ProjectExplorer.Project.Updater.FileVersion 312 | 18 313 | 314 | 315 | Version 316 | 18 317 | 318 | 319 | -------------------------------------------------------------------------------- /MRoomServer/header.h: -------------------------------------------------------------------------------- 1 | #ifndef HEADER_H 2 | #define HEADER_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "string.h" 9 | struct ImageFrameHead 10 | { 11 | int funCode; 12 | unsigned int uTransFrameTotalSize; //数据帧总大小 13 | unsigned int uTransFrameCurrSize; //数据现在的大小 14 | 15 | //数据帧变量 16 | unsigned int uDataFrameSize; //文件的大小 17 | unsigned int uDataFrametotal; //数据帧总的个数 18 | unsigned int uDataFrameCurr; //当前第几个帧 19 | unsigned int uDataInFrameOffset; //偏移量 20 | }; 21 | 22 | struct ImageUserInfo //typdef 用新的变量类型去定义新的变量 23 | { 24 | char userName[60]; 25 | unsigned int CMD; 26 | unsigned int dataSize; //头部后面的数据内容的大小 27 | ImageUserInfo() 28 | { 29 | memset(this, 0, sizeof(ImageUserInfo)); 30 | } 31 | }; 32 | 33 | struct MUserWidget 34 | { 35 | QWidget *mWidget; 36 | QLineEdit *nameLine; 37 | QLabel *mLabel; 38 | int mLabelW; 39 | int mLabelH; 40 | MUserWidget() 41 | { 42 | mLabelW = 450; 43 | mLabelH = 450; 44 | mWidget = NULL; 45 | nameLine = NULL; 46 | mLabel = NULL; 47 | } 48 | void setWH(int w, int h) 49 | { 50 | mLabelW = w; 51 | mLabelH = h; 52 | } 53 | }; 54 | 55 | typedef struct tagUserInfo 56 | { 57 | QString userName; 58 | QString userIP; 59 | qint64 recvFileData; 60 | bool chatState; 61 | bool monitorState; 62 | bool projectionState; 63 | TDataSocket *tDataSocket; 64 | int pCount; 65 | tagUserInfo() 66 | { 67 | userName = ""; 68 | userIP = "" ; 69 | recvFileData = 0; 70 | chatState = false; 71 | monitorState = false; 72 | projectionState = false; 73 | tDataSocket = NULL; 74 | pCount = 0; 75 | } 76 | }UserInfo, *PUserInfo; 77 | 78 | 79 | #endif // HEADER_H 80 | -------------------------------------------------------------------------------- /MRoomServer/images/close.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jennifer249/MultimediaNetClassroom/48ab904fb1bbfb934b668fd53155bc0057a0ba67/MRoomServer/images/close.ico -------------------------------------------------------------------------------- /MRoomServer/images/closed_128px_1229164_easyicon.net.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jennifer249/MultimediaNetClassroom/48ab904fb1bbfb934b668fd53155bc0057a0ba67/MRoomServer/images/closed_128px_1229164_easyicon.net.ico -------------------------------------------------------------------------------- /MRoomServer/logindlg.cpp: -------------------------------------------------------------------------------- 1 | #include "logindlg.h" 2 | #include "ui_logindlg.h" 3 | #include 4 | #include 5 | LoginDlg::LoginDlg(QWidget *parent) : 6 | QDialog(parent), 7 | ui(new Ui::LoginDlg) 8 | { 9 | ui->setupUi(this); 10 | init(); 11 | } 12 | 13 | LoginDlg::~LoginDlg() 14 | { 15 | delete ui; 16 | } 17 | 18 | //初始化 19 | void LoginDlg::init() 20 | { 21 | setFixedSize(300,200); 22 | setWindowTitle(tr("局域网多媒体教学软件")); 23 | setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint); 24 | ui->pwEdit ->setEchoMode(QLineEdit::Password); 25 | } 26 | 27 | //背景绘图 28 | void LoginDlg::paintEvent(QPaintEvent *event) 29 | { 30 | Q_UNUSED(event); 31 | 32 | QPainter p(this); 33 | p.setPen(Qt::NoPen); 34 | p.setBrush(Qt::white); 35 | p.drawRect(rect()); 36 | } 37 | 38 | //点击登录按钮 39 | void LoginDlg::on_loginBtn_clicked() 40 | { 41 | if(ui->IDEdit->text() == "teacher" && ui->pwEdit->text() == "123456") 42 | { 43 | MRoomServer* m = new MRoomServer(); 44 | m->setAttribute(Qt::WA_DeleteOnClose); //除了隐藏窗口,还会释放这个窗口所占的资源 45 | m->show(); 46 | this->close(); 47 | } 48 | else 49 | { 50 | QMessageBox::warning(this,tr("登录失败"),tr("账号或密码错误")); 51 | } 52 | } 53 | 54 | //点击取消按钮 55 | void LoginDlg::on_cancelBtn_clicked() 56 | { 57 | this->close(); 58 | } 59 | -------------------------------------------------------------------------------- /MRoomServer/logindlg.h: -------------------------------------------------------------------------------- 1 | #ifndef LOGINDLG_H 2 | #define LOGINDLG_H 3 | 4 | #include 5 | #include "mroomserver.h" 6 | namespace Ui { 7 | class LoginDlg; 8 | } 9 | 10 | class LoginDlg : public QDialog 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit LoginDlg(QWidget *parent = 0); 16 | ~LoginDlg(); 17 | 18 | protected: 19 | void paintEvent(QPaintEvent *event); 20 | 21 | private slots: 22 | void on_loginBtn_clicked(); 23 | void on_cancelBtn_clicked(); 24 | 25 | private: 26 | void init(); 27 | 28 | private: 29 | Ui::LoginDlg *ui; 30 | 31 | }; 32 | 33 | #endif // LOGINDLG_H 34 | -------------------------------------------------------------------------------- /MRoomServer/logindlg.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | LoginDlg 4 | 5 | 6 | 7 | 0 8 | 0 9 | 188 10 | 107 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 密码 24 | 25 | 26 | 27 | 28 | 29 | 30 | 用户名 31 | 32 | 33 | 34 | 35 | 36 | 37 | teacher 38 | 39 | 40 | 41 | 42 | 43 | 44 | 123456 45 | 46 | 47 | 48 | 49 | 50 | 51 | Qt::Vertical 52 | 53 | 54 | 55 | 20 56 | 40 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 登录 71 | 72 | 73 | 74 | 75 | 76 | 77 | 取消 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /MRoomServer/main.cpp: -------------------------------------------------------------------------------- 1 | #include "logindlg.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | LoginDlg w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /MRoomServer/monitorthread.cpp: -------------------------------------------------------------------------------- 1 | #include "monitorthread.h" 2 | 3 | MonitorThread::MonitorThread(QString userName, QObject *parent) 4 | :QObject(parent) 5 | { 6 | buf = new char[1024*1024]; 7 | memset(buf, 0, 1024); 8 | this->userName = userName; 9 | pCount = 1; 10 | } 11 | 12 | MonitorThread::~MonitorThread() 13 | { 14 | delete buf; 15 | } 16 | 17 | void MonitorThread::recvMonitor(char *imageBuf) 18 | { 19 | qDebug() << "recv ok"; 20 | ImageFrameHead *frame = (ImageFrameHead *)imageBuf; 21 | qDebug() << "pCount" << pCount <uDataFrameCurr; 22 | if(pCount != (int)frame->uDataFrameCurr) 23 | { 24 | memset(buf, 0, 1024); 25 | pCount = 1; 26 | return; 27 | } 28 | 29 | if(frame->funCode == 1) 30 | { 31 | pCount++; 32 | memcpy(buf+frame->uDataInFrameOffset, (imageBuf+sizeof(ImageFrameHead)), frame->uTransFrameCurrSize); 33 | if(frame->uDataFrameCurr == frame->uDataFrametotal) 34 | { 35 | pCount = 1; 36 | qDebug() << "==ok" <uDataFrameSize); 38 | // memset(buf, 0, 1024); 39 | } 40 | } 41 | } 42 | 43 | QString MonitorThread::getUserName() 44 | { 45 | return userName; 46 | } 47 | -------------------------------------------------------------------------------- /MRoomServer/monitorthread.h: -------------------------------------------------------------------------------- 1 | #ifndef MONITORTHREAD_H 2 | #define MONITORTHREAD_H 3 | 4 | #include 5 | #include 6 | #include "header.h" 7 | class MonitorThread : public QObject 8 | { 9 | Q_OBJECT 10 | 11 | public: 12 | MonitorThread(QString userName, QObject *parent = 0); 13 | ~MonitorThread(); 14 | QString getUserName(); 15 | void recvMonitor(char* imageBuf); 16 | 17 | 18 | private: 19 | quint16 monitorPort; 20 | char *buf; 21 | QString userName; 22 | int pCount; 23 | 24 | signals: 25 | void recvMonitorOk(QString, char*, int); 26 | }; 27 | 28 | #endif // MONITORTHREAD_H 29 | -------------------------------------------------------------------------------- /MRoomServer/mroomserver.h: -------------------------------------------------------------------------------- 1 | #ifndef MROOMSERVER_H 2 | #define MROOMSERVER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "tdatasocket.h" 10 | #include 11 | #include "sfile.h" 12 | #include "HBScreenShot.h" 13 | #include 14 | #include 15 | #include "monitorthread.h" 16 | #include "udatasocket.h" 17 | #include 18 | #include "remotecontroldlg.h" 19 | namespace Ui { 20 | class MRoomServer; 21 | } 22 | enum MsgType{UserEnter, Msg, UserLeft, PrivateChat, UserList}; 23 | 24 | class MRoomServer : public QMainWindow 25 | { 26 | Q_OBJECT 27 | 28 | public: 29 | explicit MRoomServer(QWidget *parent = 0); 30 | ~MRoomServer(); 31 | 32 | private: 33 | void init(); //初始化界面 34 | void startServer(); //开启所有端口服务 35 | void sendConMsg(QString, QString, QHostAddress); //发送主控端口消息 36 | void judgeUsers(QString); //判断用户是否重复 37 | QString getIP(); //获取IP地址 38 | void sendConBroMsg(QString, QString, quint16); //广播所有网卡消息 39 | //处理聊天服务器 40 | void userEnter(QString); //处理新用户加入 41 | void userLeft(QString, QString); //处理用户离开 42 | void showMsg(QString, QString, QString); //处理用户发送的消息 43 | void showPrivateMsg(QString, QString, QString); //处理用户发送的消息 44 | void judgeChatUsers(QString, QHostAddress); //判断新增的聊天用户是否重复 45 | PUserInfo searchUsers(QString); //寻找匹配用户 46 | void changeUserNum(); //改变用户列表的在线用户个数 47 | void broadcastMsg(TDataSocket*, MsgType, QString, QString); //广播消息 48 | bool openProjection(); 49 | bool checkProjection(); 50 | //监视 51 | void createMonitorLabel(QString monitorName, int column); //创建监视界面 52 | void setIP(); 53 | //远程控制 54 | void createRemoteControlWidget(); 55 | 56 | private slots: 57 | void recvConMsg(); //接收主控端口消息 58 | void dealChatMsg(TDataSocket*, int, QString); //处理聊天消息 59 | void setUserIP(TDataSocket*, QString); 60 | void on_sendBtn_clicked(); //点击发送聊天消息按钮 61 | void showUserList(); //显示用户列表窗口 62 | void showChat(); //显示聊天窗口 63 | void newConnection(); //新用户连接 64 | void groupTalk(); //标记群聊 65 | void privateChatChange(QListWidgetItem* item); //标记私聊 66 | void removeUser(QString, QString); //移除用户 67 | void sendFile(); //发送文件 68 | void projection(); //投影 69 | void sendHeart(); 70 | void monitor(); //监视 71 | void showMonitor(QString, char*, int); 72 | void recvFileOK(); 73 | //远程控制 74 | void remoteControl(); 75 | void on_userListWidget_customContextMenuRequested(const QPoint &pos); 76 | void showRemoteControl(char*, int); 77 | 78 | protected: 79 | void paintEvent(QPaintEvent *event); 80 | 81 | private: 82 | Ui::MRoomServer *ui; 83 | //数据 84 | quint16 controlPort; 85 | quint16 dataPort; 86 | QUdpSocket *controlSocket; 87 | UDataSocket *uDataSocket; 88 | QTcpServer *tDataServer; 89 | QString sIP; 90 | QList userInfoList; 91 | QTimer* heartTimer; 92 | QNetworkInterface intf; 93 | //界面 94 | QAction *sendFileAction; 95 | QAction *projectAction; 96 | QAction *monitorAction; 97 | QAction *showUserListAction; 98 | QAction *showChatAction; 99 | QMenu *toolMenu; 100 | QMenu *viewMenu; 101 | QGridLayout *scrollGridLayout; 102 | //聊天 103 | bool groupChatState; 104 | TDataSocket* privateTalkerSocket; 105 | //文件 106 | SFile* sFile; 107 | //投影 108 | bool projectionState; 109 | HBScreenShot *hBScr; 110 | int packetSum; 111 | int pIndex; 112 | QList pCheckNames; 113 | char *pixChar; 114 | ImageFrameHead frame; 115 | QPixmap pix; 116 | //监视 117 | bool monitorState; 118 | QList mUserWidgetList; 119 | //远程控制 120 | QWidget *remoteControlWidget; 121 | QVBoxLayout *rvBoxLayout; 122 | QLabel *remoteControlLabel; 123 | QTimer *pointTimer; 124 | QString remoteControlUser; 125 | bool remoteControlState; 126 | RemoteControlDlg* remoteControlDlg; 127 | 128 | }; 129 | 130 | #endif // MROOMSERVER_H 131 | -------------------------------------------------------------------------------- /MRoomServer/mroomserver.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MRoomServer 4 | 5 | 6 | 7 | 0 8 | 0 9 | 800 10 | 707 11 | 12 | 13 | 14 | 15 | 800 16 | 500 17 | 18 | 19 | 20 | MRoomServer 21 | 22 | 23 | 24 | 25 | 26 | 27 | false 28 | 29 | 30 | true 31 | 32 | 33 | 34 | 35 | 0 36 | 0 37 | 517 38 | 644 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 0 50 | 0 51 | 800 52 | 17 53 | 54 | 55 | 56 | 57 | 58 | TopToolBarArea 59 | 60 | 61 | false 62 | 63 | 64 | 65 | 66 | 67 | false 68 | 69 | 70 | 在线用户 71 | 72 | 73 | 2 74 | 75 | 76 | 77 | 78 | 79 | 80 | Qt::CustomContextMenu 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 聊天 90 | 91 | 92 | 2 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | true 107 | 108 | 109 | 群聊 110 | 111 | 112 | true 113 | 114 | 115 | 116 | 117 | 118 | 119 | 发送 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /MRoomServer/mserverthread.cpp: -------------------------------------------------------------------------------- 1 | #include "mserverthread.h" 2 | #include 3 | MServerThread::MServerThread(char userName[], QObject *parent) 4 | :QThread(parent) 5 | { 6 | buf = new char[1024*1024]; 7 | memset(buf, 0, 1024); 8 | this->userName = userName; 9 | cou = 0; 10 | } 11 | 12 | MServerThread::~MServerThread() 13 | { 14 | udpSocket->close(); 15 | delete buf; 16 | } 17 | 18 | void MServerThread::run() 19 | { 20 | } 21 | 22 | void MServerThread::recvMonitor(char *imageBuf) 23 | { 24 | //qDebug() << "recv ok"; 25 | ImageFrameHead *frame = (ImageFrameHead *)imageBuf; 26 | if(frame->funCode == 1) 27 | { 28 | memcpy(buf+frame->uDataInFrameOffset, (imageBuf+sizeof(ImageFrameHead)), frame->uTransFrameCurrSize); 29 | // qDebug()<<"frame->uDataFrameCurr"<uDataFrameCurr; 30 | if(frame->uDataFrameCurr == frame->uDataFrametotal) 31 | { 32 | qDebug()<<"cou:"<uDataFrametotal"<uDataFrametotal; 34 | emit recvMonitorOk(userName, buf, frame->uDataFrameSize); 35 | memset(buf, 0, 1024); 36 | } 37 | } 38 | } 39 | 40 | char* MServerThread:: getUserName() 41 | { 42 | return userName; 43 | } 44 | -------------------------------------------------------------------------------- /MRoomServer/mserverthread.h: -------------------------------------------------------------------------------- 1 | #ifndef PCLIENTTHREAD_H 2 | #define PCLIENTTHREAD_H 3 | 4 | #include 5 | #include 6 | #include "header.h" 7 | class MServerThread : public QThread 8 | { 9 | Q_OBJECT 10 | public: 11 | MServerThread(char userName[], QObject *parent = 0); 12 | ~MServerThread(); 13 | char* getUserName(); 14 | void recvMonitor(char* imageBuf); 15 | int cou; 16 | 17 | protected: 18 | virtual void run(); 19 | 20 | private: 21 | QUdpSocket *udpSocket; 22 | quint16 monitorPort; 23 | char *buf; 24 | char *userName; 25 | 26 | signals: 27 | void recvMonitorOk(char*, char*, int); 28 | 29 | }; 30 | 31 | #endif // PCLIENTTHREAD_H 32 | -------------------------------------------------------------------------------- /MRoomServer/remotecontroldlg.cpp: -------------------------------------------------------------------------------- 1 | #include "remotecontroldlg.h" 2 | #include "ui_remotecontroldlg.h" 3 | #include 4 | RemoteControlDlg::RemoteControlDlg(QString userName, QString userIP, quint16 controlPort, QWidget *parent) : 5 | QDialog(parent), 6 | ui(new Ui::RemoteControlDlg) 7 | { 8 | ui->setupUi(this); 9 | setWindowTitle(tr("学生控制:")+userName); 10 | setWindowFlags(Qt::WindowCloseButtonHint | Qt::WindowMinMaxButtonsHint); 11 | this->userName = userName; 12 | this->userIP = userIP; 13 | this->controlPort = controlPort; 14 | this->setMouseTracking(true); 15 | } 16 | 17 | RemoteControlDlg::~RemoteControlDlg() 18 | { 19 | delete ui; 20 | } 21 | //背景绘图 22 | void RemoteControlDlg::paintEvent(QPaintEvent *event) 23 | { 24 | // Q_UNUSED(event); 25 | 26 | // //设置背景色 27 | // QPalette palette(this->palette()); 28 | // palette.setColor(QPalette::Background, Qt::black); 29 | // this->setPalette(palette); 30 | // this->setAutoFillBackground(true); 31 | // this->setPalette(palette); 32 | 33 | QPainter painter(this); 34 | painter.drawPixmap( 0, 0, this->width(), this->height(),pixmap); 35 | } 36 | 37 | void RemoteControlDlg::resizeEvent(QResizeEvent *event) 38 | { 39 | event->accept(); 40 | QString winwidth; 41 | winwidth.setNum(this->width()); 42 | QString winheight; 43 | winheight.setNum(this->height()); 44 | sendRemoteMsg("WINSIZE",winwidth,winheight); 45 | } 46 | 47 | void RemoteControlDlg::mousePressEvent(QMouseEvent *event) 48 | { 49 | event->accept(); 50 | QString xx; 51 | xx.setNum(event->windowPos().x()); 52 | QString yy; 53 | yy.setNum(event->windowPos().y()); 54 | if(event->button()==Qt::LeftButton) 55 | { 56 | sendRemoteMsg("POI_LPRESS",xx,yy); 57 | } 58 | if(event->button()==Qt::RightButton) 59 | { 60 | sendRemoteMsg("POI_RPRESS",xx,yy); 61 | } 62 | } 63 | void RemoteControlDlg::mouseMoveEvent(QMouseEvent *event) 64 | { 65 | event->accept(); 66 | QString xx; 67 | xx.setNum(event->windowPos().x()); 68 | QString yy; 69 | yy.setNum(event->windowPos().y()); 70 | sendRemoteMsg("POI_MOVE",xx,yy); 71 | } 72 | 73 | void RemoteControlDlg::mouseReleaseEvent(QMouseEvent *event) 74 | { 75 | event->accept(); 76 | QString xx; 77 | xx.setNum(event->windowPos().x()); 78 | QString yy; 79 | yy.setNum(event->windowPos().y()); 80 | if(event->button()==Qt::LeftButton) 81 | { 82 | sendRemoteMsg("POI_LRELEASE",xx,yy); 83 | } 84 | if(event->button()==Qt::RightButton) 85 | { 86 | sendRemoteMsg("POI_RRELEASE",xx,yy); 87 | } 88 | } 89 | 90 | void RemoteControlDlg::mouseDoubleClickEvent(QMouseEvent *event) 91 | { 92 | event->accept(); 93 | QString xx; 94 | xx.setNum(event->windowPos().x()); 95 | QString yy; 96 | yy.setNum(event->windowPos().y()); 97 | sendRemoteMsg("POI_DCLICK",xx,yy); 98 | } 99 | 100 | void RemoteControlDlg::keyPressEvent(QKeyEvent *event) 101 | { 102 | event->accept(); 103 | QString keynum; 104 | keynum.setNum(event->key()); 105 | sendRemoteMsg("KEY_PRESS",keynum,event->text()); 106 | } 107 | 108 | void RemoteControlDlg::keyReleaseEvent(QKeyEvent *event) 109 | { 110 | event->accept(); 111 | QString keynum; 112 | keynum.setNum(event->key()); 113 | sendRemoteMsg("KEY_RELEASE",keynum,event->text()); 114 | } 115 | 116 | void RemoteControlDlg::sendRemoteMsg(QString mouseType, QString msga, QString msgb) 117 | { 118 | QString name = "Teacher"; 119 | QString type = "CON_REMOTEMSG"; 120 | QByteArray sData; 121 | QDataStream out(&sData, QIODevice::WriteOnly); 122 | out << name; 123 | out << type; 124 | out << mouseType; 125 | out << msga; 126 | out << msgb; 127 | qDebug() << "mouseType:"<writeDatagram(sData, sData.length(), QHostAddress(userIP), controlPort); 129 | } 130 | 131 | void RemoteControlDlg::setSocket(QUdpSocket * udpSocket) 132 | { 133 | this->udpSocket = udpSocket; 134 | } 135 | 136 | void RemoteControlDlg::showRemoteControl(char *buf, int length) 137 | { 138 | qDebug() << "here"; 139 | pixmap.loadFromData((uchar*)buf, length, "JPG"); 140 | this->update(); 141 | // int width = ui->remoteControlLabel->width()*0.9; 142 | // int height = ui->remoteControlLabel->height()*0.9; 143 | // QPixmap fitPixmap = pixmap.scaled(width,height,Qt::IgnoreAspectRatio,Qt::SmoothTransformation); 144 | // ui->remoteControlLabel->setPixmap(fitPixmap); 145 | // ui->remoteControlLabel->setAlignment(Qt::AlignCenter); 146 | 147 | // QPainter painter(this); 148 | // painter.drawPixmap( 0, 0, this->width(), this->height(),pixmap); 149 | } 150 | 151 | void RemoteControlDlg::closeEvent(QCloseEvent *event) 152 | { 153 | QString name = "Teacher"; 154 | QString type = "CON_STOP_REMOTECONTROL"; 155 | QByteArray sData; 156 | QDataStream out(&sData, QIODevice::WriteOnly); 157 | out << name; 158 | out << type; 159 | udpSocket->writeDatagram(sData, sData.length(), QHostAddress(userIP), controlPort); 160 | } 161 | -------------------------------------------------------------------------------- /MRoomServer/remotecontroldlg.h: -------------------------------------------------------------------------------- 1 | #ifndef REMOTECONTROLDLG_H 2 | #define REMOTECONTROLDLG_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | namespace Ui { 9 | class RemoteControlDlg; 10 | } 11 | 12 | class RemoteControlDlg : public QDialog 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit RemoteControlDlg(QString userName, QString userIP, quint16 controlPort, QWidget *parent = 0); 18 | ~RemoteControlDlg(); 19 | void setSocket(QUdpSocket *); 20 | void showRemoteControl(char *buf, int length); 21 | 22 | private: 23 | void sendRemoteMsg(QString, QString, QString); 24 | 25 | protected: 26 | void resizeEvent(QResizeEvent *event); 27 | void closeEvent(QCloseEvent *event); 28 | void mousePressEvent(QMouseEvent *event); 29 | void mouseMoveEvent(QMouseEvent *event); 30 | void mouseReleaseEvent(QMouseEvent *event); 31 | void mouseDoubleClickEvent(QMouseEvent *event); 32 | void keyPressEvent(QKeyEvent *event); 33 | void keyReleaseEvent(QKeyEvent *event); 34 | 35 | private: 36 | Ui::RemoteControlDlg *ui; 37 | QUdpSocket *udpSocket; 38 | QString userName; 39 | QString userIP; 40 | quint16 controlPort; 41 | QPixmap pixmap; 42 | protected: 43 | void paintEvent(QPaintEvent *event); 44 | }; 45 | 46 | #endif // REMOTECONTROLDLG_H 47 | -------------------------------------------------------------------------------- /MRoomServer/remotecontroldlg.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | RemoteControlDlg 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /MRoomServer/resource.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | images/close.ico 4 | 5 | 6 | -------------------------------------------------------------------------------- /MRoomServer/sfile.cpp: -------------------------------------------------------------------------------- 1 | #include "sfile.h" 2 | #include "ui_sfile.h" 3 | #include 4 | #include 5 | 6 | SFile::SFile(QList userInfoList,QWidget *parent) : 7 | QDialog(parent), 8 | ui(new Ui::SFile) 9 | { 10 | ui->setupUi(this); 11 | setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint); 12 | this->userInfoList = userInfoList; 13 | } 14 | 15 | SFile::~SFile() 16 | { 17 | delete ui; 18 | } 19 | 20 | void SFile::on_openBtn_clicked() 21 | { 22 | filePath = QFileDialog::getOpenFileName(this); 23 | if(!filePath.isEmpty()) 24 | { 25 | fileName = filePath.right(filePath.size()-filePath.lastIndexOf('/')-1); //匹配从右边开始的子项 26 | ui->msgLabel->setText(tr("要传送的文件为:%1").arg(fileName)); 27 | ui->sendBtn->setEnabled(true); 28 | ui->openBtn->setEnabled(false); 29 | } 30 | } 31 | 32 | void SFile::on_sendBtn_clicked() 33 | { 34 | writtenSum = 0; 35 | ui->msgLabel->setText(tr("准备发送文件 %1 ").arg(fileName)); 36 | ui->sendBtn->setEnabled(false); 37 | for(int i=0; itDataSocket, SIGNAL(fileWarning(QString)),this, SLOT(fileWarning(QString))); 40 | connect(userInfoList.at(i)->tDataSocket, SIGNAL(updateProgressBar(QString, qint64,qint64,float)),this,SLOT(updateProgressBar(QString, qint64,qint64,float))); 41 | userInfoList.at(i)->tDataSocket->writeFile(filePath); 42 | } 43 | } 44 | 45 | void SFile::fileWarning(QString error) 46 | { 47 | QMessageBox::warning(this, tr("应用程序"), tr("无法读取文件 %1:\n%2").arg(fileName).arg(error)); 48 | } 49 | 50 | void SFile::updateProgressBar(QString userName, qint64 totalBytes, qint64 bytesWritten, float useTime) 51 | { 52 | 53 | qDebug() << totalBytes << bytesWritten << userName <userName == userName) 57 | { 58 | writtenSum -= userInfoList.at(i)->recvFileData; 59 | userInfoList.at(i)->recvFileData = bytesWritten; 60 | writtenSum += bytesWritten; 61 | } 62 | } 63 | 64 | ui->progressBar->setMaximum(totalBytes*userInfoList.count()); 65 | ui->progressBar->setValue(writtenSum); 66 | 67 | double speed = totalBytes*userInfoList.count() / useTime; 68 | QString msg = tr("已发送%1MB(%2MB/s \n共%3MB 已用时:%4秒\n估计剩余时间:%5s)") 69 | .arg((double)writtenSum/(1024*1024),0,'f',2) 70 | .arg(speed*1000/(1024*1024),0,'f',2) 71 | .arg((double)totalBytes*userInfoList.count()/(1024*1024),0,'f',2) 72 | .arg(useTime/1000,0,'f',0) 73 | .arg((double)totalBytes*userInfoList.count()/speed/1000 - useTime/1000,0,'f',0); 74 | ui->msgLabel->setText(msg); 75 | 76 | qDebug() << "updateProgressBar" << writtenSum << totalBytes*userInfoList.count(); 77 | if(writtenSum == totalBytes*userInfoList.count()) 78 | { 79 | ui->msgLabel->setText(tr("传送文件%1成功").arg(fileName)); 80 | writtenSum = 0; 81 | for(int i=0; irecvFileData = 0; 84 | } 85 | } 86 | } 87 | 88 | void SFile::on_closeBtn_clicked() 89 | { 90 | this->close(); 91 | } 92 | -------------------------------------------------------------------------------- /MRoomServer/sfile.h: -------------------------------------------------------------------------------- 1 | #ifndef SFILE_H 2 | #define SFILE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | namespace Ui { 9 | class SFile; 10 | } 11 | 12 | class SFile : public QDialog 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit SFile(QList, QWidget *parent = 0); 18 | ~SFile(); 19 | 20 | private slots: 21 | void on_openBtn_clicked(); 22 | void on_sendBtn_clicked(); 23 | void fileWarning(QString); 24 | void updateProgressBar(QString, qint64,qint64,float); 25 | 26 | void on_closeBtn_clicked(); 27 | 28 | private: 29 | Ui::SFile *ui; 30 | QString filePath; 31 | QString fileName; 32 | QList userInfoList; 33 | 34 | qint64 totalBytes; //总共 35 | qint64 bytesWritten; //已经写的 36 | qint64 bytesTobeWrite; //剩下的 37 | qint64 payloadSize; 38 | QTime time; 39 | qint64 writtenSum; 40 | }; 41 | 42 | #endif // SFILE_H 43 | -------------------------------------------------------------------------------- /MRoomServer/sfile.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | SFile 4 | 5 | 6 | 7 | 0 8 | 0 9 | 248 10 | 124 11 | 12 | 13 | 14 | 文件传输 15 | 16 | 17 | 18 | 19 | 20 | 选择文件/文件夹 21 | 22 | 23 | 24 | 25 | 26 | 27 | 打开... 28 | 29 | 30 | 31 | 32 | 33 | 34 | 发送 35 | 36 | 37 | 38 | 39 | 40 | 41 | 0 42 | 43 | 44 | 45 | 46 | 47 | 48 | 关闭 49 | 50 | 51 | 52 | 53 | 54 | 55 | 请选择要发送的文件! 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /MRoomServer/sfserver.cpp: -------------------------------------------------------------------------------- 1 | #include "sfserver.h" 2 | #include "ui_sfserver.h" 3 | #include 4 | #include 5 | 6 | int userCount = 0; 7 | SFServer::SFServer(quint16 sFilePort,QWidget *parent) : 8 | QDialog(parent), 9 | ui(new Ui::SFServer) 10 | { 11 | ui->setupUi(this); 12 | this->sFilePort = sFilePort; 13 | tcpServer = new QTcpServer(this); 14 | connect(tcpServer,SIGNAL(newConnection()),this,SLOT(newUsers())); 15 | initServerWin(); 16 | //监听 17 | if(!tcpServer->listen(QHostAddress::Any,sFilePort)) 18 | { 19 | qDebug() << tcpServer->errorString(); 20 | close(); 21 | return; 22 | } 23 | } 24 | // [0]界面初始化 25 | void SFServer::initServerWin() 26 | { 27 | 28 | ui->msgLabel->setText(tr("请选择要传送的文件")); 29 | ui->progressBar->reset(); 30 | ui->openBtn->setEnabled(true); 31 | ui->sendBtn->setEnabled(false); 32 | userCount = 0; 33 | tcpServer->close(); 34 | } 35 | // [0]界面初始化 36 | 37 | void SFServer::closeEvent(QCloseEvent *e) 38 | { 39 | emit closeThread(); 40 | e->accept(); 41 | } 42 | void SFServer::newUsers() 43 | { 44 | int socketDescriptor = tcpServer->nextPendingConnection()->socketDescriptor(); 45 | SFSocketThread *thread = new SFSocketThread(this,socketDescriptor); 46 | userCount++; 47 | thread->start(); 48 | connect(thread,SIGNAL(updateFileWritten(qint64,qint64,QString)),this,SLOT(updateProgressBar(qint64,qint64,QString))); 49 | connect(thread,SIGNAL(fileWarningToSer(QString)),this,SLOT(fileWarning(QString))); 50 | 51 | } 52 | void SFServer::fileWarning(QString error) 53 | { 54 | QMessageBox::warning(this, tr("应用程序"), tr("无法读取文件 %1:\n%2").arg(fileName).arg(error)); 55 | } 56 | 57 | void SFServer::updateProgressBar(qint64 totalBytes,qint64 bytesWritten,QString msg) 58 | { 59 | ui->progressBar->setMaximum(totalBytes*userCount); 60 | ui->progressBar->setValue(bytesWritten); 61 | ui->msgLabel->setText(msg); 62 | if(bytesWritten == totalBytes*userCount) 63 | { 64 | ui->msgLabel->setText(tr("传送文件%1成功").arg(theFileName)); 65 | ui->progressBar->setValue(totalBytes); 66 | userCount = 0; 67 | bytesWritten = 0; 68 | tcpServer->close(); 69 | } 70 | } 71 | 72 | SFServer::~SFServer() 73 | { 74 | delete ui; 75 | } 76 | 77 | void SFServer::on_sendBtn_clicked() 78 | { 79 | ui->msgLabel->setText(tr("准备发送文件 %1 ").arg(theFileName)); 80 | ui->sendBtn->setEnabled(false); 81 | emit sendFile(fileName); 82 | } 83 | 84 | void SFServer::on_openBtn_clicked() 85 | { 86 | fileName = QFileDialog::getOpenFileName(this); 87 | if(!fileName.isEmpty()) 88 | { 89 | theFileName = fileName.right(fileName.size()-fileName.lastIndexOf('/')-1); //匹配从右边开始的子项 90 | ui->msgLabel->setText(tr("要传送的文件为:%1").arg(theFileName)); 91 | ui->sendBtn->setEnabled(true); 92 | ui->openBtn->setEnabled(false); 93 | } 94 | } 95 | 96 | void SFServer::on_closeBtn_clicked() 97 | { 98 | if(tcpServer->isListening()) 99 | { 100 | tcpServer->close(); 101 | } 102 | close(); 103 | } 104 | -------------------------------------------------------------------------------- /MRoomServer/sfserver.h: -------------------------------------------------------------------------------- 1 | #ifndef FILESERVER_H 2 | #define FILESERVER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "sfsocketthread.h" 9 | 10 | namespace Ui { 11 | class SFServer; 12 | } 13 | 14 | class SFServer : public QDialog 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | explicit SFServer(quint16 sFilePort = 16663,QWidget *parent = 0); 20 | ~SFServer(); 21 | 22 | private: 23 | Ui::SFServer *ui; 24 | QTcpServer *tcpServer; 25 | QString fileName; 26 | QString theFileName; 27 | 28 | quint16 sFilePort; 29 | 30 | protected: 31 | void initServerWin(); 32 | void closeEvent(QCloseEvent *e); 33 | private slots: 34 | void on_sendBtn_clicked(); 35 | void on_openBtn_clicked(); 36 | void on_closeBtn_clicked(); 37 | void updateProgressBar(qint64,qint64,QString); 38 | void newUsers(); 39 | void fileWarning(QString); 40 | signals: 41 | void sendFile(QString); 42 | void closeThread(); 43 | }; 44 | 45 | #endif // FILESERVER_H 46 | -------------------------------------------------------------------------------- /MRoomServer/tdatasocket.cpp: -------------------------------------------------------------------------------- 1 | #include "tdatasocket.h" 2 | #include 3 | 4 | TDataSocket::TDataSocket(QTcpSocket* tSocket, QObject *parent) 5 | :QThread(parent) 6 | { 7 | tcpSocket = tSocket; 8 | fileState = false; 9 | QObject::connect(tcpSocket, SIGNAL(readyRead()),this,SLOT(recvTDataMsg())); 10 | QObject::connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(ConnectErr())); 11 | connect(tcpSocket,SIGNAL(bytesWritten(qint64)),this,SLOT(continueSend(qint64))); 12 | 13 | //发送文件 14 | payloadSize = 64*1024; 15 | totalBytes = 0; 16 | bytesWritten = 0; 17 | bytesTobeWrite = 0; 18 | 19 | recvTotalBytes = 0; 20 | bytesReceived = 0; 21 | fileNameSize = 0; 22 | blockSize = 0; 23 | } 24 | 25 | void TDataSocket::run() 26 | { 27 | exec(); 28 | } 29 | 30 | //处理接收消息 31 | void TDataSocket::recvTDataMsg() 32 | { 33 | if(tcpSocket->bytesAvailable() <= 0) 34 | return; 35 | 36 | //临时读取缓冲区的所有数据 37 | QByteArray tempBuffer; 38 | tempBuffer = tcpSocket->readAll(); 39 | //上次缓冲加上这次的数据 40 | tPendingBuffer.append(tempBuffer); 41 | ushort CMD; 42 | pendingDataSize = tPendingBuffer.size(); 43 | while(pendingDataSize) 44 | { 45 | QDataStream in(tPendingBuffer); 46 | in.setByteOrder(QDataStream::BigEndian); 47 | 48 | //不够包头的数据不处理 49 | if(pendingDataSize < (int)sizeof(ushort)) 50 | break; 51 | 52 | in >> CMD; 53 | 54 | qDebug() <> len; 61 | if(pendingDataSize < (int)len) 62 | break; 63 | 64 | int type; 65 | QString msg = NULL; 66 | in >> type >> msg; 67 | if(type == 0) 68 | { 69 | QString IP = NULL; 70 | in >> IP; 71 | qDebug() << "userIP" << IP; 72 | emit setUserIP(this,IP); 73 | } 74 | emit dealChatMsg(this, type, msg); 75 | //总的数据,前面部分已处理,将后面部分缓存 76 | tempBuffer = tPendingBuffer.right(pendingDataSize - len); 77 | //更新长度 78 | pendingDataSize = tempBuffer.size(); 79 | //更新待处理的数据 80 | tPendingBuffer = tempBuffer; 81 | } 82 | else if(CMD == (ushort)1) 83 | { 84 | if (bytesReceived <= sizeof(qint64)*2+(int)sizeof(ushort)) //先获得前两个数据,文件的大小、文件名的大小 85 | { 86 | if ((pendingDataSize >= (int)sizeof(qint64)*2+(int)sizeof(ushort)) && (fileNameSize == 0)) 87 | { 88 | in >> recvTotalBytes >> fileNameSize; //获得文件的大小、文件名的大小 89 | bytesReceived += sizeof(qint64)*2+(int)sizeof(ushort); 90 | pendingDataSize -= (int)sizeof(qint64)*2+(int)sizeof(ushort); 91 | } 92 | if((pendingDataSize >= fileNameSize) && (fileNameSize != 0)){ //获取文件名 93 | in >> fileName; 94 | bytesReceived += fileNameSize; 95 | pendingDataSize -= fileNameSize; 96 | } 97 | else 98 | { 99 | updatePending(bytesReceived); 100 | //数据不足等下次 101 | return; 102 | } 103 | updatePending(bytesReceived); 104 | } 105 | if(!fileName.isEmpty() && locFile == Q_NULLPTR) 106 | { 107 | locFile = new QFile(userName+"_"+fileName); 108 | if(!locFile->open(QFile::WriteOnly)) 109 | { 110 | qDebug()<< "File Open Failed"; 111 | delete locFile; 112 | locFile = Q_NULLPTR; 113 | return; 114 | } 115 | } 116 | 117 | if(locFile == Q_NULLPTR) 118 | return; 119 | 120 | int writeMin = qMin(pendingDataSize-(int)sizeof(ushort), (int)(recvTotalBytes-bytesReceived)); 121 | if (bytesReceived < recvTotalBytes) { 122 | bytesReceived += writeMin; 123 | qDebug() << "writeMin" << writeMin; 124 | locFile->write(tPendingBuffer.right(pendingDataSize-(int)sizeof(ushort)), writeMin); 125 | updatePending(writeMin+(int)sizeof(ushort)); 126 | } 127 | 128 | if(bytesReceived == recvTotalBytes) 129 | { 130 | locFile->close(); 131 | locFile = Q_NULLPTR; 132 | fileName = ""; 133 | recvTotalBytes = 0; 134 | bytesReceived = 0; 135 | fileNameSize = 0; 136 | blockSize = 0; 137 | tempBuffer = tPendingBuffer.right(pendingDataSize-(int)sizeof(ushort)); 138 | //更新长度 139 | pendingDataSize = tempBuffer.size(); 140 | //更新待处理的数据 141 | tPendingBuffer = tempBuffer; 142 | qDebug() << pendingDataSize; 143 | emit recvFileOK(); 144 | } 145 | return; 146 | } 147 | } 148 | } 149 | 150 | //发送聊天消息 151 | void TDataSocket::writeChatMsg(int type, QString userName, QString msg, QString time) 152 | { 153 | QByteArray block; 154 | QDataStream out(&block,QIODevice::WriteOnly); 155 | out.setByteOrder(QDataStream::BigEndian); 156 | out << ushort(0) << quint64(0) << type << userName << msg << time; 157 | out.device()->seek(0); 158 | ushort CMD = 0; //聊天 159 | quint64 len = (quint64)block.size(); 160 | out << CMD << len; 161 | qDebug() << "send:" << CMD << len; 162 | tcpSocket->write(block); 163 | } 164 | 165 | //发送文件 166 | void TDataSocket::writeFile(QString filePath) 167 | { 168 | fileState = true; 169 | localFile = new QFile(filePath); 170 | if(!localFile->open(QFile::ReadOnly)) 171 | { 172 | emit fileWarning(localFile->errorString()); 173 | return; 174 | } 175 | totalBytes = localFile->size(); //文件大小 176 | 177 | qDebug() << "totalBytes" <seek(0); 185 | ushort CMD = (ushort)1; //文件 186 | out << CMD << totalBytes << qint64(fileBlock.size()-sizeof(qint64)*2-sizeof(ushort)); //写入总文件大小,文件名大小 187 | qDebug() << CMD << totalBytes << qint64(fileBlock.size()-sizeof(qint64)*2-sizeof(ushort)); 188 | bytesTobeWrite = totalBytes - tcpSocket->write(fileBlock); //发送首部后,计算剩余大小 189 | fileBlock.resize(0); 190 | } 191 | 192 | void TDataSocket::continueSend(qint64 numBytes) 193 | { 194 | if(fileState == false) 195 | return; 196 | bytesWritten += (int)numBytes; 197 | 198 | //发送进度条 199 | float useTime = time.elapsed(); 200 | emit updateProgressBar(userName,totalBytes,bytesWritten,useTime); 201 | 202 | if(bytesTobeWrite > 0) 203 | { 204 | fileBlock = localFile->read(qMin(bytesTobeWrite,payloadSize)); //读取该大小的数据 205 | bytesTobeWrite -= (int)tcpSocket->write(fileBlock); //写入 206 | qDebug() << "bytesTobeWrite" << bytesTobeWrite << qMin(bytesTobeWrite,payloadSize); 207 | } 208 | else 209 | { 210 | if(localFile->isOpen()) 211 | localFile->close(); 212 | fileBlock.resize(0); 213 | fileState = false; 214 | totalBytes = 0; 215 | bytesWritten = 0; 216 | bytesTobeWrite = 0; 217 | } 218 | 219 | if(bytesWritten == totalBytes) 220 | { 221 | if(localFile->isOpen()) 222 | localFile->close(); 223 | fileBlock.resize(0); 224 | fileState = false; 225 | totalBytes = 0; 226 | bytesWritten = 0; 227 | bytesTobeWrite = 0; 228 | } 229 | } 230 | 231 | 232 | //更新缓冲区数据 233 | void TDataSocket::updatePending(int len) 234 | { 235 | QByteArray temp; 236 | QDataStream out(&temp,QIODevice::WriteOnly); 237 | out << (ushort)1; 238 | //总的数据,前面部分已处理,将后面部分缓存 239 | temp.append(tPendingBuffer.right(tPendingBuffer.size()-len)); 240 | //更新长度 241 | pendingDataSize = temp.size(); 242 | //更新待处理的数据 243 | tPendingBuffer = temp; 244 | } 245 | 246 | //设置tcpSocket的用户姓名 247 | void TDataSocket::setUserName(QString userName) 248 | { 249 | this->userName = userName; 250 | } 251 | 252 | //获取该tcpSocket的用户姓名 253 | QString TDataSocket::getUserName() 254 | { 255 | return userName; 256 | } 257 | 258 | //关闭tcpSocket 259 | void TDataSocket::dealClose() 260 | { 261 | qDebug() << "dealClose"; 262 | tcpSocket = NULL; 263 | } 264 | 265 | //tcpSocket连接错误消息 266 | void TDataSocket::ConnectErr() 267 | { 268 | tcpSocket = NULL; 269 | qDebug() << "服务器的 tDataSocket 连接错误"; 270 | QString time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm"); 271 | emit removeUser(userName, time); 272 | } 273 | -------------------------------------------------------------------------------- /MRoomServer/tdatasocket.h: -------------------------------------------------------------------------------- 1 | #ifndef TDATASOCKET_H 2 | #define TDATASOCKET_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | class TDataSocket : public QThread 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit TDataSocket(QTcpSocket *tSocket, QObject *parent = 0); 15 | void setUserName(QString); //设置用户名 16 | QString getUserName(); //获取用户名 17 | void writeChatMsg(int, QString, QString, QString); //发送聊天消息 18 | void writeFile(QString); 19 | private: 20 | void updatePending(int); 21 | signals: 22 | void dealChatMsg(TDataSocket*, int, QString); //发送待处理聊天消息信号 23 | void setUserIP(TDataSocket*, QString); 24 | void removeUser(QString, QString); //发送移除用户消息 25 | void fileWarning(QString); 26 | void updateProgressBar(QString, qint64,qint64,float); 27 | void recvFileOK(); 28 | private slots: 29 | void recvTDataMsg(); //接收消息 30 | void ConnectErr(); //连接错误 31 | void dealClose(); //关闭tcpSocket,被调用 32 | void continueSend(qint64); 33 | protected: 34 | virtual void run(); 35 | 36 | private: 37 | //tcp沾包处理 38 | QByteArray tRecvData; 39 | qint64 tDataSize; 40 | qint64 tCheckSize; 41 | QByteArray tPendingBuffer; 42 | QTcpSocket* tcpSocket; 43 | QString userName; 44 | //写文件 45 | QFile* localFile; 46 | qint64 totalBytes; //总共 47 | qint64 bytesWritten; //已经写的 48 | qint64 bytesTobeWrite; //剩下的 49 | qint64 payloadSize; 50 | QTime time; 51 | QByteArray fileBlock; 52 | bool fileState; 53 | //接收文件 54 | qint64 recvTotalBytes; 55 | qint64 bytesReceived; 56 | qint64 fileNameSize; 57 | QString fileName; 58 | QFile *locFile = Q_NULLPTR; 59 | quint16 blockSize; 60 | int pendingDataSize; 61 | }; 62 | 63 | #endif // TDATASOCKET_H 64 | -------------------------------------------------------------------------------- /MRoomServer/udatasocket.cpp: -------------------------------------------------------------------------------- 1 | #include "udatasocket.h" 2 | 3 | UDataSocket::UDataSocket(quint16 port, QNetworkInterface intf, QString sIP, QObject *parent) 4 | :QThread(parent) 5 | { 6 | buf = new char[1024*1024]; 7 | memset(buf, 0, 1024*1024); 8 | dataPort = port; 9 | pCount = 1; 10 | this->intf = intf; 11 | this->sIP = sIP; 12 | } 13 | 14 | void UDataSocket::run() 15 | { 16 | uDataSocket = new QUdpSocket; 17 | if(!uDataSocket->bind(QHostAddress(sIP), dataPort,QUdpSocket::ShareAddress|QUdpSocket::ReuseAddressHint)) 18 | qDebug()<<"bind failed--"; 19 | uDataSocket->setSocketOption(QAbstractSocket::ReceiveBufferSizeSocketOption,1024*1024*8); 20 | uDataSocket->setMulticastInterface(intf); 21 | connect(uDataSocket, SIGNAL(readyRead()), this, SLOT(recvPicture()),Qt::DirectConnection); 22 | exec(); 23 | } 24 | 25 | //分发收到的UDP帧,分别处理 26 | void UDataSocket::recvPicture() 27 | { 28 | char *recvBuf = new char[1116]; 29 | memset(recvBuf,0,1116); 30 | while(uDataSocket->hasPendingDatagrams()) 31 | { 32 | bool flag = false; 33 | memset(recvBuf,0,1116); 34 | int pDataSize = uDataSocket->pendingDatagramSize(); 35 | //qDebug() << "dataSize:" << pDataSize; 36 | 37 | uDataSocket->readDatagram(recvBuf, pDataSize); 38 | ImageUserInfo *imageUserInfo = (ImageUserInfo *)recvBuf; 39 | 40 | qDebug() << "imageUserInfo->userName" << imageUserInfo->userName; 41 | if(imageUserInfo->CMD == 0) 42 | { 43 | char *imageBuf = new char[imageUserInfo->dataSize]; 44 | memcpy(imageBuf, (recvBuf+sizeof(ImageUserInfo)), imageUserInfo->dataSize); 45 | for(int i=0; iuserName" <userName << mUserList.count()<<"item->getUserName()"<getUserName(); 49 | if(QString::compare(QString(imageUserInfo->userName), item->getUserName())==0) 50 | { 51 | flag = true; 52 | item->recvMonitor(imageBuf); 53 | } 54 | } 55 | if(flag == false) 56 | { 57 | QThread thread; 58 | MonitorThread *newM = new MonitorThread(QString(imageUserInfo->userName)); 59 | newM->moveToThread(&thread); 60 | connect(newM,SIGNAL(recvMonitorOk(QString, char*, int)),this,SIGNAL(recvMonitorOk(QString, char*, int))); 61 | mUserList.append(newM); 62 | newM->recvMonitor(imageBuf); 63 | qDebug() <<"imageUserInfo->userName" <userName<CMD == 1) 67 | { 68 | ImageFrameHead *frame = (ImageFrameHead *)(imageUserInfo+1); 69 | qDebug() << "pCount" << pCount <uDataFrameCurr; 70 | if(pCount != (int)frame->uDataFrameCurr) 71 | { 72 | memset(buf, 0, 1024); 73 | pCount = 1; 74 | return; 75 | } 76 | 77 | if(frame->funCode == 1) 78 | { 79 | pCount++; 80 | memcpy(buf+frame->uDataInFrameOffset, (recvBuf+sizeof(ImageUserInfo)+sizeof(ImageFrameHead)), frame->uTransFrameCurrSize); 81 | if(frame->uDataFrameCurr == frame->uDataFrametotal) 82 | { 83 | pCount = 1; 84 | qDebug() << "==ok" <userName; 85 | emit recvRemoteControlOk(buf, frame->uDataFrameSize); 86 | // memset(buf, 0, 1024); 87 | } 88 | } 89 | } 90 | 91 | } 92 | delete recvBuf; 93 | } 94 | 95 | qint64 UDataSocket::write(char *data, qint64 size, QHostAddress address) 96 | { 97 | return uDataSocket->writeDatagram(data,size,address,dataPort); 98 | } 99 | -------------------------------------------------------------------------------- /MRoomServer/udatasocket.h: -------------------------------------------------------------------------------- 1 | #ifndef UDATASOCKET_H 2 | #define UDATASOCKET_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "monitorthread.h" 8 | class UDataSocket : public QThread 9 | { 10 | Q_OBJECT 11 | public: 12 | UDataSocket(quint16 port, QNetworkInterface intf, QString sIP, QObject* parent = 0); 13 | qint64 write(char*, qint64, QHostAddress); 14 | protected: 15 | virtual void run(); 16 | 17 | private: 18 | QUdpSocket* uDataSocket; 19 | quint16 dataPort; 20 | char *buf; 21 | int pCount; 22 | QNetworkInterface intf; 23 | QList mUserList; 24 | QObject *parent; 25 | QString sIP; 26 | 27 | private slots: 28 | void recvPicture(); 29 | 30 | signals: 31 | void recvMonitorOk(QString, char*, int); 32 | void recvRemoteControlOk(char*, int); 33 | }; 34 | 35 | #endif // UDATASOCKET_H 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MultimediaNetClassroom 2 | 基于局域网在Qt Creator 4.6.0平台上采用C/S架构、Windows API编程以及Qt5图形开发包实现,心跳检测、消息通信、文件传输、广播投影(含鼠标)、学生监视、学生控制功能 3 | --------------------------------------------------------------------------------