├── ChatRoom.exe
├── README.md
├── chatRoom
├── ChatRoom.ico
├── ChatRoom.pro
├── ChatRoom.pro.user
├── ChatRoom.pro.user.0360db3
├── ChatRoom.pro.user.383c2b9
├── ChatRoom.pro.user.b25dcfa
├── ChatRoom.pro.user.f898218
├── addfriends.cpp
├── addfriends.h
├── chatroom.cpp
├── chatroom.h
├── command.h
├── drawer.cpp
├── drawer.h
├── friendslist.cpp
├── friendslist.h
├── images.qrc
├── images
│ ├── 1.png
│ ├── ChatRoom.jpg
│ ├── Linux.jpg
│ ├── boss.png
│ ├── jj.png
│ ├── jj2.png
│ ├── l.png
│ ├── liu.png
│ ├── m.png
│ ├── m2.png
│ ├── qq.png
│ ├── w.png
│ ├── w2.png
│ ├── z.png
│ └── zz.png
├── information.h
├── main.cpp
├── onlinestate.cpp
├── onlinestate.h
├── sign.cpp
├── sign.h
├── tcpclient.cpp
├── tcpclient.h
├── widget.cpp
├── widget.h
└── widget.ui
├── server_mysql
├── Makefile
├── MyReactor.cpp
├── MyReactor.h
├── command.h
├── main
└── main.cpp
└── spdlog-1.x.zip
/ChatRoom.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CXHGT/TCP-ChatRoom/99790ff02ae5bb040e525390561b8d769ec9415b/ChatRoom.exe
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TCP-ChatRoom
2 | 基于云服务器的TCP网络聊天室【客户端Qt5.6开发、后台服务器多进程实现、Mysql数据库管理用户信息】
3 | - **客户端**
4 |
5 | win10下的客户端
6 |
7 | 
8 |
9 | Ubuntu下客户端
10 |
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 | 日志库spdlog需要把其文件夹中的include/spdlog 文件夹放到Linux系统/usr/include 目录下
46 |
47 | 数据库相关函数需要mysql.h头文件,需要Linux系统安装mysql软件
48 |
49 | sudo apt-get install mysql-server
50 |
51 | sudo apt-get install libmysqlclient-dev[开发包,不安装会提示找不到mysql.h头文件]
52 |
53 | 我用的数据库名称叫做ChatRoom,若你的mysql中没有这一数据库,会提示连接数据库失败
54 |
55 | 保存用户信息的表的结构,在上面给出的图片可以看到
56 |
57 | 服务器IP为腾讯云服务器IP,这样可以保证公网下的用户都能连接上,测试时要修改为你的本地IP,客户端,服务器端都要改
58 |
--------------------------------------------------------------------------------
/chatRoom/ChatRoom.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CXHGT/TCP-ChatRoom/99790ff02ae5bb040e525390561b8d769ec9415b/chatRoom/ChatRoom.ico
--------------------------------------------------------------------------------
/chatRoom/ChatRoom.pro:
--------------------------------------------------------------------------------
1 | #-------------------------------------------------
2 | #
3 | # Project created by QtCreator 2018-07-13T15:04:31
4 | #
5 | #-------------------------------------------------
6 |
7 | QT += core gui
8 | QT += network
9 |
10 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
11 |
12 | TARGET = ChatRoom
13 | TEMPLATE = app
14 |
15 | # The following define makes your compiler emit warnings if you use
16 | # any feature of Qt which as been marked as deprecated (the exact warnings
17 | # depend on your compiler). Please consult the documentation of the
18 | # deprecated API in order to know how to port your code away from it.
19 | DEFINES += QT_DEPRECATED_WARNINGS
20 |
21 | # You can also make your code fail to compile if you use deprecated APIs.
22 | # In order to do so, uncomment the following line.
23 | # You can also select to disable deprecated APIs only up to a certain version of Qt.
24 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
25 |
26 |
27 | SOURCES += main.cpp\
28 | sign.cpp \
29 | drawer.cpp \
30 | tcpclient.cpp \
31 | addfriends.cpp \
32 | friendslist.cpp \
33 | onlinestate.cpp
34 |
35 | HEADERS += \
36 | sign.h \
37 | command.h \
38 | drawer.h \
39 | tcpclient.h \
40 | addfriends.h \
41 | friendslist.h \
42 | onlinestate.h
43 |
44 | FORMS +=
45 |
46 | RESOURCES += \
47 | images.qrc
48 | RC_ICONS = ChatRoom.ico
49 |
--------------------------------------------------------------------------------
/chatRoom/ChatRoom.pro.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | EnvironmentId
7 | {f8982184-467d-44fa-be12-d0f9d607f079}
8 |
9 |
10 | ProjectExplorer.Project.ActiveTarget
11 | 0
12 |
13 |
14 | ProjectExplorer.Project.EditorSettings
15 |
16 | true
17 | false
18 | true
19 |
20 | Cpp
21 |
22 | CppGlobal
23 |
24 |
25 |
26 | QmlJS
27 |
28 | QmlJSGlobal
29 |
30 |
31 | 2
32 | UTF-8
33 | false
34 | 4
35 | false
36 | 80
37 | true
38 | true
39 | 1
40 | true
41 | false
42 | 0
43 | true
44 | 0
45 | 8
46 | true
47 | 1
48 | true
49 | true
50 | true
51 | false
52 |
53 |
54 |
55 | ProjectExplorer.Project.PluginSettings
56 |
57 |
58 |
59 | ProjectExplorer.Project.Target.0
60 |
61 | Desktop Qt 5.6.0 MinGW 32bit
62 | Desktop Qt 5.6.0 MinGW 32bit
63 | qt.56.win32_mingw49_kit
64 | 1
65 | 0
66 | 0
67 |
68 | C:/Users/Realself/Desktop/SoftWareFiles/QtCreator/build-chatRoom-Desktop_Qt_5_6_0_MinGW_32bit-Debug
69 |
70 |
71 | true
72 | qmake
73 |
74 | QtProjectManager.QMakeBuildStep
75 | true
76 |
77 | false
78 | false
79 | false
80 |
81 |
82 | true
83 | Make
84 |
85 | Qt4ProjectManager.MakeStep
86 |
87 | false
88 |
89 |
90 |
91 | 2
92 | 构建
93 |
94 | ProjectExplorer.BuildSteps.Build
95 |
96 |
97 |
98 | true
99 | Make
100 |
101 | Qt4ProjectManager.MakeStep
102 |
103 | true
104 | clean
105 |
106 |
107 | 1
108 | 清理
109 |
110 | ProjectExplorer.BuildSteps.Clean
111 |
112 | 2
113 | false
114 |
115 | Debug
116 |
117 | Qt4ProjectManager.Qt4BuildConfiguration
118 | 2
119 | true
120 |
121 |
122 | C:/Users/Realself/Desktop/SoftWareFiles/QtCreator/build-chatRoom-Desktop_Qt_5_6_0_MinGW_32bit-Release
123 |
124 |
125 | true
126 | qmake
127 |
128 | QtProjectManager.QMakeBuildStep
129 | false
130 |
131 | false
132 | false
133 | false
134 |
135 |
136 | true
137 | Make
138 |
139 | Qt4ProjectManager.MakeStep
140 |
141 | false
142 |
143 |
144 |
145 | 2
146 | 构建
147 |
148 | ProjectExplorer.BuildSteps.Build
149 |
150 |
151 |
152 | true
153 | Make
154 |
155 | Qt4ProjectManager.MakeStep
156 |
157 | true
158 | clean
159 |
160 |
161 | 1
162 | 清理
163 |
164 | ProjectExplorer.BuildSteps.Clean
165 |
166 | 2
167 | false
168 |
169 | Release
170 |
171 | Qt4ProjectManager.Qt4BuildConfiguration
172 | 0
173 | true
174 |
175 |
176 | C:/Users/Realself/Downloads/chatRoom-master/daySix/build-ChatRoom-Desktop_Qt_5_6_0_MinGW_32bit-Profile
177 |
178 |
179 | true
180 | qmake
181 |
182 | QtProjectManager.QMakeBuildStep
183 | true
184 |
185 | false
186 | true
187 | false
188 |
189 |
190 | true
191 | Make
192 |
193 | Qt4ProjectManager.MakeStep
194 |
195 | false
196 |
197 |
198 |
199 | 2
200 | 构建
201 |
202 | ProjectExplorer.BuildSteps.Build
203 |
204 |
205 |
206 | true
207 | Make
208 |
209 | Qt4ProjectManager.MakeStep
210 |
211 | true
212 | clean
213 |
214 |
215 | 1
216 | 清理
217 |
218 | ProjectExplorer.BuildSteps.Clean
219 |
220 | 2
221 | false
222 |
223 | Profile
224 |
225 | Qt4ProjectManager.Qt4BuildConfiguration
226 | 0
227 | true
228 |
229 | 3
230 |
231 |
232 | 0
233 | 部署
234 |
235 | ProjectExplorer.BuildSteps.Deploy
236 |
237 | 1
238 | 在本地部署
239 |
240 | ProjectExplorer.DefaultDeployConfiguration
241 |
242 | 1
243 |
244 |
245 | false
246 | 1000
247 |
248 | true
249 |
250 | false
251 | false
252 | false
253 | false
254 | true
255 | 0.01
256 | 10
257 | true
258 | 1
259 | 25
260 |
261 | 1
262 | true
263 | false
264 | true
265 | valgrind
266 |
267 | 0
268 | 1
269 | 2
270 | 3
271 | 4
272 | 5
273 | 6
274 | 7
275 | 8
276 | 9
277 | 10
278 | 11
279 | 12
280 | 13
281 | 14
282 |
283 | 2
284 |
285 | ChatRoom
286 | ChatRoom2
287 | Qt4ProjectManager.Qt4RunConfiguration:C:/Users/Realself/Desktop/SoftWareFiles/QtCreator/chatRoom/ChatRoom.pro
288 | true
289 |
290 | ChatRoom.pro
291 | false
292 | false
293 |
294 | 3768
295 | false
296 | true
297 | false
298 | false
299 | true
300 |
301 | 1
302 |
303 |
304 |
305 | ProjectExplorer.Project.TargetCount
306 | 1
307 |
308 |
309 | ProjectExplorer.Project.Updater.FileVersion
310 | 18
311 |
312 |
313 | Version
314 | 18
315 |
316 |
317 |
--------------------------------------------------------------------------------
/chatRoom/ChatRoom.pro.user.0360db3:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | EnvironmentId
7 | {0360db30-20c5-4c1d-9aaf-58d00c53f6cd}
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.8.0 MinGW 32bit
63 | Desktop Qt 5.8.0 MinGW 32bit
64 | qt.58.win32_mingw53_kit
65 | 0
66 | 0
67 | 0
68 |
69 | D:/QT/build-ChatRoom-Desktop_Qt_5_8_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 | D:/QT/build-ChatRoom-Desktop_Qt_5_8_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 | D:/QT/build-ChatRoom-Desktop_Qt_5_8_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 | ChatRoom
288 |
289 | Qt4ProjectManager.Qt4RunConfiguration:D:/QT/ChatRoom/ChatRoom.pro
290 | true
291 |
292 | ChatRoom.pro
293 | false
294 |
295 | D:/QT/build-ChatRoom-Desktop_Qt_5_8_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 |
--------------------------------------------------------------------------------
/chatRoom/ChatRoom.pro.user.383c2b9:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | EnvironmentId
7 | {383c2b94-d5e2-4e15-b8e8-b6cb3f698278}
8 |
9 |
10 | ProjectExplorer.Project.ActiveTarget
11 | 0
12 |
13 |
14 | ProjectExplorer.Project.EditorSettings
15 |
16 | true
17 | false
18 | true
19 |
20 | Cpp
21 |
22 | CppGlobal
23 |
24 |
25 |
26 | QmlJS
27 |
28 | QmlJSGlobal
29 |
30 |
31 | 2
32 | UTF-8
33 | false
34 | 4
35 | false
36 | 80
37 | true
38 | true
39 | 1
40 | true
41 | false
42 | 0
43 | true
44 | 0
45 | 8
46 | true
47 | 1
48 | true
49 | true
50 | true
51 | false
52 |
53 |
54 |
55 | ProjectExplorer.Project.PluginSettings
56 |
57 |
58 |
59 | ProjectExplorer.Project.Target.0
60 |
61 | Desktop Qt 5.6.0 GCC 64bit
62 | Desktop Qt 5.6.0 GCC 64bit
63 | qt.56.gcc_64_kit
64 | 0
65 | 0
66 | 0
67 |
68 | /home/mtf/文档/LinuxNetwork/ChatRoom/daySeven
69 |
70 |
71 | true
72 | qmake
73 |
74 | QtProjectManager.QMakeBuildStep
75 | true
76 |
77 | false
78 | false
79 | false
80 |
81 |
82 | true
83 | Make
84 |
85 | Qt4ProjectManager.MakeStep
86 |
87 | -w
88 | -r
89 |
90 | false
91 |
92 |
93 |
94 | 2
95 | 构建
96 |
97 | ProjectExplorer.BuildSteps.Build
98 |
99 |
100 |
101 | true
102 | Make
103 |
104 | Qt4ProjectManager.MakeStep
105 |
106 | -w
107 | -r
108 |
109 | true
110 | clean
111 |
112 |
113 | 1
114 | 清理
115 |
116 | ProjectExplorer.BuildSteps.Clean
117 |
118 | 2
119 | false
120 |
121 | Debug
122 |
123 | Qt4ProjectManager.Qt4BuildConfiguration
124 | 2
125 | true
126 |
127 |
128 | /home/mtf/下载/chatRoom-master/daySix/build-ChatRoom-Desktop_Qt_5_6_0_GCC_64bit-Release
129 |
130 |
131 | true
132 | qmake
133 |
134 | QtProjectManager.QMakeBuildStep
135 | false
136 |
137 | false
138 | false
139 | false
140 |
141 |
142 | true
143 | Make
144 |
145 | Qt4ProjectManager.MakeStep
146 |
147 | -w
148 | -r
149 |
150 | false
151 |
152 |
153 |
154 | 2
155 | 构建
156 |
157 | ProjectExplorer.BuildSteps.Build
158 |
159 |
160 |
161 | true
162 | Make
163 |
164 | Qt4ProjectManager.MakeStep
165 |
166 | -w
167 | -r
168 |
169 | true
170 | clean
171 |
172 |
173 | 1
174 | 清理
175 |
176 | ProjectExplorer.BuildSteps.Clean
177 |
178 | 2
179 | false
180 |
181 | Release
182 |
183 | Qt4ProjectManager.Qt4BuildConfiguration
184 | 0
185 | true
186 |
187 |
188 | /home/mtf/下载/chatRoom-master/daySix/build-ChatRoom-Desktop_Qt_5_6_0_GCC_64bit-Profile
189 |
190 |
191 | true
192 | qmake
193 |
194 | QtProjectManager.QMakeBuildStep
195 | true
196 |
197 | false
198 | true
199 | false
200 |
201 |
202 | true
203 | Make
204 |
205 | Qt4ProjectManager.MakeStep
206 |
207 | -w
208 | -r
209 |
210 | false
211 |
212 |
213 |
214 | 2
215 | 构建
216 |
217 | ProjectExplorer.BuildSteps.Build
218 |
219 |
220 |
221 | true
222 | Make
223 |
224 | Qt4ProjectManager.MakeStep
225 |
226 | -w
227 | -r
228 |
229 | true
230 | clean
231 |
232 |
233 | 1
234 | 清理
235 |
236 | ProjectExplorer.BuildSteps.Clean
237 |
238 | 2
239 | false
240 |
241 | Profile
242 |
243 | Qt4ProjectManager.Qt4BuildConfiguration
244 | 0
245 | true
246 |
247 | 3
248 |
249 |
250 | 0
251 | 部署
252 |
253 | ProjectExplorer.BuildSteps.Deploy
254 |
255 | 1
256 | 在本地部署
257 |
258 | ProjectExplorer.DefaultDeployConfiguration
259 |
260 | 1
261 |
262 |
263 | false
264 | 1000
265 |
266 | true
267 |
268 | false
269 | false
270 | false
271 | false
272 | true
273 | 0.01
274 | 10
275 | true
276 | 1
277 | 25
278 |
279 | 1
280 | true
281 | false
282 | true
283 | valgrind
284 |
285 | 0
286 | 1
287 | 2
288 | 3
289 | 4
290 | 5
291 | 6
292 | 7
293 | 8
294 | 9
295 | 10
296 | 11
297 | 12
298 | 13
299 | 14
300 |
301 | 2
302 |
303 | ChatRoom
304 |
305 | Qt4ProjectManager.Qt4RunConfiguration:/home/mtf/文档/LinuxNetwork/ChatRoom/daySeven/chatRoom/ChatRoom.pro
306 | true
307 |
308 | ChatRoom.pro
309 | false
310 | false
311 |
312 | 3768
313 | false
314 | true
315 | false
316 | false
317 | true
318 |
319 | 1
320 |
321 |
322 |
323 | ProjectExplorer.Project.TargetCount
324 | 1
325 |
326 |
327 | ProjectExplorer.Project.Updater.FileVersion
328 | 18
329 |
330 |
331 | Version
332 | 18
333 |
334 |
335 |
--------------------------------------------------------------------------------
/chatRoom/ChatRoom.pro.user.f898218:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | EnvironmentId
7 | {f8982184-467d-44fa-be12-d0f9d607f079}
8 |
9 |
10 | ProjectExplorer.Project.ActiveTarget
11 | 0
12 |
13 |
14 | ProjectExplorer.Project.EditorSettings
15 |
16 | true
17 | false
18 | true
19 |
20 | Cpp
21 |
22 | CppGlobal
23 |
24 |
25 |
26 | QmlJS
27 |
28 | QmlJSGlobal
29 |
30 |
31 | 2
32 | UTF-8
33 | false
34 | 4
35 | false
36 | 80
37 | true
38 | true
39 | 1
40 | true
41 | false
42 | 0
43 | true
44 | 0
45 | 8
46 | true
47 | 1
48 | true
49 | true
50 | true
51 | false
52 |
53 |
54 |
55 | ProjectExplorer.Project.PluginSettings
56 |
57 |
58 |
59 | ProjectExplorer.Project.Target.0
60 |
61 | Desktop Qt 5.6.0 MinGW 32bit
62 | Desktop Qt 5.6.0 MinGW 32bit
63 | qt.56.win32_mingw49_kit
64 | 0
65 | 0
66 | 0
67 |
68 | C:/Users/Realself/Downloads/chatRoom-master/daySix/build-ChatRoom-Desktop_Qt_5_6_0_MinGW_32bit-Debug
69 |
70 |
71 | true
72 | qmake
73 |
74 | QtProjectManager.QMakeBuildStep
75 | true
76 |
77 | false
78 | false
79 | false
80 |
81 |
82 | true
83 | Make
84 |
85 | Qt4ProjectManager.MakeStep
86 |
87 | false
88 |
89 |
90 |
91 | 2
92 | 构建
93 |
94 | ProjectExplorer.BuildSteps.Build
95 |
96 |
97 |
98 | true
99 | Make
100 |
101 | Qt4ProjectManager.MakeStep
102 |
103 | true
104 | clean
105 |
106 |
107 | 1
108 | 清理
109 |
110 | ProjectExplorer.BuildSteps.Clean
111 |
112 | 2
113 | false
114 |
115 | Debug
116 |
117 | Qt4ProjectManager.Qt4BuildConfiguration
118 | 2
119 | true
120 |
121 |
122 | C:/Users/Realself/Downloads/chatRoom-master/daySix/build-ChatRoom-Desktop_Qt_5_6_0_MinGW_32bit-Release
123 |
124 |
125 | true
126 | qmake
127 |
128 | QtProjectManager.QMakeBuildStep
129 | false
130 |
131 | false
132 | false
133 | false
134 |
135 |
136 | true
137 | Make
138 |
139 | Qt4ProjectManager.MakeStep
140 |
141 | false
142 |
143 |
144 |
145 | 2
146 | 构建
147 |
148 | ProjectExplorer.BuildSteps.Build
149 |
150 |
151 |
152 | true
153 | Make
154 |
155 | Qt4ProjectManager.MakeStep
156 |
157 | true
158 | clean
159 |
160 |
161 | 1
162 | 清理
163 |
164 | ProjectExplorer.BuildSteps.Clean
165 |
166 | 2
167 | false
168 |
169 | Release
170 |
171 | Qt4ProjectManager.Qt4BuildConfiguration
172 | 0
173 | true
174 |
175 |
176 | C:/Users/Realself/Downloads/chatRoom-master/daySix/build-ChatRoom-Desktop_Qt_5_6_0_MinGW_32bit-Profile
177 |
178 |
179 | true
180 | qmake
181 |
182 | QtProjectManager.QMakeBuildStep
183 | true
184 |
185 | false
186 | true
187 | false
188 |
189 |
190 | true
191 | Make
192 |
193 | Qt4ProjectManager.MakeStep
194 |
195 | false
196 |
197 |
198 |
199 | 2
200 | 构建
201 |
202 | ProjectExplorer.BuildSteps.Build
203 |
204 |
205 |
206 | true
207 | Make
208 |
209 | Qt4ProjectManager.MakeStep
210 |
211 | true
212 | clean
213 |
214 |
215 | 1
216 | 清理
217 |
218 | ProjectExplorer.BuildSteps.Clean
219 |
220 | 2
221 | false
222 |
223 | Profile
224 |
225 | Qt4ProjectManager.Qt4BuildConfiguration
226 | 0
227 | true
228 |
229 | 3
230 |
231 |
232 | 0
233 | 部署
234 |
235 | ProjectExplorer.BuildSteps.Deploy
236 |
237 | 1
238 | 在本地部署
239 |
240 | ProjectExplorer.DefaultDeployConfiguration
241 |
242 | 1
243 |
244 |
245 | false
246 | 1000
247 |
248 | true
249 |
250 | false
251 | false
252 | false
253 | false
254 | true
255 | 0.01
256 | 10
257 | true
258 | 1
259 | 25
260 |
261 | 1
262 | true
263 | false
264 | true
265 | valgrind
266 |
267 | 0
268 | 1
269 | 2
270 | 3
271 | 4
272 | 5
273 | 6
274 | 7
275 | 8
276 | 9
277 | 10
278 | 11
279 | 12
280 | 13
281 | 14
282 |
283 | 2
284 |
285 | ChatRoom
286 |
287 | Qt4ProjectManager.Qt4RunConfiguration:C:/Users/Realself/Downloads/chatRoom-master/daySix/ChatRoom/ChatRoom.pro
288 | true
289 |
290 | ChatRoom.pro
291 | false
292 | false
293 |
294 | 3768
295 | false
296 | true
297 | false
298 | false
299 | true
300 |
301 | 1
302 |
303 |
304 |
305 | ProjectExplorer.Project.TargetCount
306 | 1
307 |
308 |
309 | ProjectExplorer.Project.Updater.FileVersion
310 | 18
311 |
312 |
313 | Version
314 | 18
315 |
316 |
317 |
--------------------------------------------------------------------------------
/chatRoom/addfriends.cpp:
--------------------------------------------------------------------------------
1 | #include "addfriends.h"
2 | #include "command.h"
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | AddFriends::AddFriends(QWidget *parent)
10 | : QDialog(parent)
11 | {
12 | setWindowTitle(tr("添加好友"));
13 | this->setFixedSize(300,200);
14 |
15 | nameLabel = new QLabel(tr("Name:"));
16 | nameLineEdit = new QLineEdit();
17 | enterBtn = new QPushButton("Enter");
18 |
19 | tcpSocket = new QTcpSocket(this);
20 |
21 | mainLayout = new QGridLayout(this);
22 | mainLayout->addWidget(nameLabel, 0, 0);
23 | mainLayout->addWidget(nameLineEdit, 0, 1);
24 | mainLayout->addWidget(enterBtn, 1, 1);
25 |
26 | //连接服务器
27 | port = 12345;
28 | serverIP = new QHostAddress();
29 | QString ip = SERVER_IP;
30 | serverIP->setAddress(ip);
31 |
32 | connect(enterBtn, SIGNAL(clicked()), this, SLOT(slotEnter()));
33 | connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(dataReceived()));
34 | }
35 |
36 |
37 | AddFriends::~AddFriends()
38 | {
39 | tcpSocket->disconnectFromHost();
40 | }
41 | //在关闭窗口之前,断开与服务器的连接
42 | void AddFriends::closeEvent(QCloseEvent *event)
43 | {
44 | tcpSocket->disconnectFromHost();
45 | tcpSocket->waitForDisconnected();
46 | event->accept();
47 | }
48 | void AddFriends::slotEnter()
49 | {
50 | tcpSocket->connectToHost(*serverIP, port);
51 | if(nameLineEdit->text() == "")
52 | {
53 | QMessageBox::warning(this, tr("Name is empty"), tr("Name is empty"));
54 | return;
55 | }
56 | QString msg = tr(ADDFRIENDS);
57 | toname=nameLineEdit->text();
58 | msg += username+"+"+toname;
59 | int length=tcpSocket->write(msg.toLatin1(), msg.toLatin1().length());
60 | if(length != msg.length())
61 | {
62 | return;
63 | }
64 | this->hide();
65 | }
66 |
67 | void AddFriends::dataReceived()
68 | {
69 | QByteArray datagram;
70 | datagram.resize(tcpSocket->bytesAvailable());
71 | tcpSocket->read(datagram.data(), datagram.size());
72 | QString msg = datagram.data();
73 |
74 | if(msg == "The name is wrong")
75 | {
76 | QMessageBox::warning(this, tr("the message from server..."), tr("The name is wrong"));
77 | this->show();
78 | }
79 | else if(msg == "message has been sended")
80 | {
81 | QMessageBox::information(this, tr("the message from server..."), tr("message has been sended"));
82 | tcpSocket->disconnectFromHost();
83 | }
84 | else if(msg=="you are have been friends!")
85 | {
86 | QMessageBox::information(this, tr("the message from server..."), tr("you are have been friends!"));
87 | this->show();
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/chatRoom/addfriends.h:
--------------------------------------------------------------------------------
1 | #ifndef ADDFRIENDS_H
2 | #define ADDFRIENDS_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include "command.h"
13 |
14 | class AddFriends : public QDialog
15 | {
16 | Q_OBJECT
17 | public:
18 | AddFriends(QWidget *parent = 0);
19 | ~AddFriends();
20 | public:
21 | QString username;
22 | QString toname;
23 | private:
24 | QGridLayout *mainLayout;
25 | QLabel *nameLabel;
26 | QLineEdit *nameLineEdit;
27 | QPushButton *enterBtn;
28 | void closeEvent(QCloseEvent *event);//关闭事件
29 | int port;
30 | QHostAddress *serverIP;
31 | QTcpSocket *tcpSocket;
32 |
33 | public slots:
34 | void slotEnter();
35 | void dataReceived();
36 | };
37 |
38 | #endif // ADDFRIENDS_H
39 |
--------------------------------------------------------------------------------
/chatRoom/chatroom.cpp:
--------------------------------------------------------------------------------
1 | #include "chatroom.h"
2 | #include
3 | #include
4 |
5 | ChatRoom::ChatRoom(QWidget *parent,Qt::WindowFlags f)
6 | : QDialog(parent,f)
7 | {
8 | setWindowTitle(tr("TCP Client"));
9 | contentListWidget = new QListWidget;
10 | sendLineEdit = new QLineEdit;
11 | sendBtn = new QPushButton(tr("Send"));
12 | clearBtn = new QPushButton(tr("Clear"));
13 | enterBtn= new QPushButton(tr("Enter Chat Room"));
14 | mainLayout = new QGridLayout(this);
15 | mainLayout->addWidget(contentListWidget,0,0,1,3);
16 | mainLayout->addWidget(sendLineEdit,1,0);
17 | mainLayout->addWidget(sendBtn,1,1);
18 | mainLayout->addWidget(clearBtn,1,2);
19 | mainLayout->addWidget(enterBtn,2,0,1,3);
20 |
21 |
22 | status = false;
23 | //连接服务器
24 | port = 12345;
25 | IP = "172.29.1.82";
26 | serverIP = new QHostAddress();
27 | connect(enterBtn, SIGNAL(clicked()), this, SLOT(slotEnter()));
28 | connect(sendBtn, SIGNAL(clicked()), this, SLOT(slotSend()));
29 | connect(clearBtn, SIGNAL(clicked()), this, SLOT(slotClear()));
30 | sendBtn->setEnabled(false);
31 | }
32 |
33 | ChatRoom::~ChatRoom()
34 | {
35 | }
36 |
37 | void ChatRoom::slotEnter()
38 | {
39 | if(!status)
40 | {
41 | /* 完成输入合法性检验 */
42 | if(!serverIP->setAddress(IP))
43 | {
44 | QMessageBox::information(this,tr("error"),tr("server ip address error!"));
45 | return;
46 | }
47 |
48 | /* 创建了一个QTcpSocket类对象,并将信号/槽连接起来 */
49 | tcpSocket = new QTcpSocket(this);
50 | connect(tcpSocket, SIGNAL(connected()), this, SLOT (slotConnected()));
51 | connect(tcpSocket, SIGNAL(disconnected()), this, SLOT (slotDisconnected ()));
52 | connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(dataReceived()));
53 | tcpSocket->connectToHost(*serverIP, port);
54 | status = true;
55 | sendBtn->setEnabled(true);
56 | }
57 | else
58 | {
59 | int length = 0;
60 | QString msg = tr(" :Leave Chat Room");
61 | if((length = tcpSocket->write(msg.toLatin1(),msg. length()))!=msg. length())
62 | {
63 | return;
64 | }
65 | tcpSocket->disconnectFromHost();
66 | status = false; //将status状态复位
67 | }
68 | }
69 |
70 | void ChatRoom::slotConnected()
71 | {
72 | enterBtn->setText(tr("leave"));
73 | int length = 0;
74 | QString msg = tr(" :Enter Chat Room");
75 | if((length = tcpSocket->write(msg.toLatin1(), msg.length())) != msg.length())
76 | {
77 | return;
78 | }
79 | }
80 |
81 | void ChatRoom::slotSend()
82 | {
83 | if(sendLineEdit->text() == "")
84 | {
85 | return;
86 | }
87 | QString msg = sendLineEdit->text();
88 | tcpSocket->write(msg.toLatin1(), msg.length());
89 | sendLineEdit->clear();
90 | }
91 |
92 | void ChatRoom::slotDisconnected()
93 | {
94 | sendBtn->setEnabled(false);
95 | enterBtn->setText(tr("Enter Chat Room"));
96 | }
97 |
98 | void ChatRoom::slotClear()
99 | {
100 | contentListWidget->clear();
101 | }
102 |
103 | void ChatRoom::dataReceived()
104 | {
105 | while(tcpSocket->bytesAvailable()>0)
106 | {
107 | QByteArray datagram;
108 | datagram.resize(tcpSocket->bytesAvailable());
109 | tcpSocket->read(datagram.data(),datagram.size());
110 | QString msg=datagram.data();
111 | contentListWidget->addItem(msg.left(datagram.size()));
112 | contentListWidget->scrollToBottom();
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/chatRoom/chatroom.h:
--------------------------------------------------------------------------------
1 | #ifndef CHATROOM_H
2 | #define CHATROOM_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include "command.h"
14 |
15 | class ChatRoom : public QDialog
16 | {
17 | Q_OBJECT
18 |
19 | public:
20 | ChatRoom(QWidget *parent = 0,Qt::WindowFlags f=0);
21 | ~ChatRoom();
22 |
23 | private:
24 | QListWidget *contentListWidget;
25 | QLineEdit *sendLineEdit;
26 | QPushButton *sendBtn;
27 | QPushButton *clearBtn;
28 | QPushButton *enterBtn;
29 | QGridLayout *mainLayout;
30 | bool status;
31 | int port;
32 | QString IP;
33 | QHostAddress *serverIP;
34 | QTcpSocket *tcpSocket;
35 |
36 | public slots:
37 | void slotEnter();
38 | void slotConnected();
39 | void slotDisconnected();
40 | void dataReceived();
41 | void slotSend();
42 | void slotClear();
43 | };
44 |
45 |
46 | #endif // CHATROOM_H
47 |
--------------------------------------------------------------------------------
/chatRoom/command.h:
--------------------------------------------------------------------------------
1 | #ifndef COMMAND_H
2 | #define COMMAND_H
3 |
4 | #define SERVER_IP "122.51.90.199"
5 | #define REGISTER "1"
6 | #define LOGIN "2"
7 | #define MESSAGE "3"
8 | #define ADDFRIENDS "4"
9 | #define ADDREQUEST "5"
10 | #define ACCEPT "6"
11 | #define REFUSE "7"
12 | #define FRIENDSLIST "8"
13 | #define ONLINE "9"
14 | #define ONLINESTATE "o"
15 | #define PICCHANGE "p"
16 | #endif // COMMAND_H
17 |
--------------------------------------------------------------------------------
/chatRoom/drawer.cpp:
--------------------------------------------------------------------------------
1 | #include "drawer.h"
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | Drawer::Drawer(QWidget *parent, Qt::WindowFlags f)
8 | :QToolBox(parent,f)
9 | {
10 | this->setWindowFlags(Qt::FramelessWindowHint);//去掉边框
11 | setWindowTitle(tr("Chat Room"));
12 | setWindowIcon(QPixmap(":/images/ChatRoom.jpg"));
13 |
14 | initialMapstylestring();
15 | tabWidget=new QTabWidget(this);
16 | QWidget *sysWidget=new QWidget;
17 | QVBoxLayout *sysLayout=new QVBoxLayout(sysWidget);
18 | addFriendsBtn = new QPushButton(tr("添加好友"));
19 | connect(addFriendsBtn, SIGNAL(clicked()), this, SLOT(slotAddFriends()));
20 | QPushButton *EnterChatRoom=new QPushButton(tr("聊天室"));
21 | connect(EnterChatRoom, SIGNAL(clicked()), this, SLOT(showChatWidget1()));
22 | QPushButton *QuitButton=new QPushButton(tr("退出客户端"));
23 | connect(QuitButton, SIGNAL(clicked()), this, SLOT(Quit()));
24 | SelectMapStytle=new QComboBox(this);
25 | SelectMapStytle->addItem(tr("修改头像"));//项目编号从0开始
26 | SelectMapStytle->addItem(tr("汪老板"));
27 | SelectMapStytle->addItem(tr("刘老板"));
28 | SelectMapStytle->addItem(tr("赵老师"));
29 | SelectMapStytle->addItem(tr("周老师"));
30 | SelectMapStytle->addItem(tr("小飞飞"));
31 | SelectMapStytle->addItem(tr("BOSS"));
32 | SelectMapStytle->addItem(tr("军军"));
33 | SelectMapStytle->addItem(tr("军军2号"));
34 | SelectMapStytle->addItem(tr("小飞飞2号"));
35 | SelectMapStytle->addItem(tr("汪老板2号"));
36 | SelectMapStytle->setCurrentIndex(0);
37 | connect(SelectMapStytle,SIGNAL(currentIndexChanged(int)),this,SLOT(MapStytleSet()));
38 | sysLayout->setMargin(20);
39 | sysLayout->setAlignment(Qt::AlignTop);//设置顶部对齐
40 | sysLayout->addWidget(addFriendsBtn);
41 | sysLayout->addWidget(EnterChatRoom);
42 | sysLayout->addWidget(SelectMapStytle);
43 | sysLayout->addWidget(QuitButton);
44 | sysWidget->setLayout(sysLayout);
45 |
46 | myFriends=new QWidget;
47 | friLayout=new QVBoxLayout(myFriends);
48 | myFriends->setLayout(friLayout);
49 | friLayout->setAlignment(Qt::AlignTop);//设置顶部对齐
50 |
51 | tabWidget->addTab(sysWidget,"系统功能");
52 | tabWidget->addTab(myFriends,"我的好友");
53 |
54 | toolBtn1 = new QToolButton(this);
55 | toolBtn1->setIcon(QPixmap(":/images/qq.png"));
56 | toolBtn1->setIconSize(QPixmap(":/images/qq.png").size());
57 | toolBtn1->setAutoRaise(true);
58 | toolBtn1->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
59 | //toolBtn1->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
60 | //connect(toolBtn1, SIGNAL(clicked()), this, SLOT(showChatWidget1()));
61 |
62 | toolBtn2 = new QToolButton(this);
63 | toolBtn2->setIcon(QPixmap(":/images/1.png"));
64 | //toolBtn2->setIconSize(QPixmap(":/images/1.png").size());
65 | toolBtn2->setAutoRaise(true);
66 | toolBtn2->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
67 | toolBtn2->setText("new message");
68 | toolBtn2->hide();
69 | connect(toolBtn2, SIGNAL(clicked()), this, SLOT(showaddfriendWidget()));
70 |
71 | QGroupBox *groupBox = new QGroupBox;
72 | QVBoxLayout *layout = new QVBoxLayout(groupBox);
73 | layout->setMargin(0);
74 | layout->setAlignment(Qt::AlignLeft);
75 | layout->addWidget(toolBtn1);
76 | layout->addWidget(tabWidget);
77 | layout->addWidget(toolBtn2);
78 | //layout->addStretch(); //插入一个占位符
79 |
80 | this->addItem((QWidget*)groupBox, tr("Client"));
81 | addflag=false;
82 | refuseflag=false;
83 | changefunc=false;
84 | PicChangeflag=false;
85 |
86 | getfdlTimer=new QTimer(this);
87 | connect(getfdlTimer,SIGNAL(timeout()),this,SLOT(getFDL()));
88 | getfdlTimer->start(10);
89 |
90 | havedoneTimer=new QTimer(this);
91 | connect(havedoneTimer,SIGNAL(timeout()),this,SLOT(CheckFlag()));
92 | havedoneTimer->start(100);
93 |
94 |
95 | onlineStateTimer=new QTimer(this);
96 | connect(onlineStateTimer,SIGNAL(timeout()),this,SLOT(CheckonlineState()));
97 |
98 | users=new userInfo[20];
99 |
100 | }
101 |
102 | void Drawer::initialMapstylestring()
103 | {
104 | MapStytle[0]=":/images/qq.png";
105 | MapStytle[1]=":/images/w.png";
106 | MapStytle[2]=":/images/l.png";
107 | MapStytle[3]=":/images/zz.png";
108 | MapStytle[4]=":/images/z.png";
109 | MapStytle[5]=":/images/m.png";
110 | MapStytle[6]=":/images/boss.png";
111 | MapStytle[7]=":/images/jj.png";
112 | MapStytle[8]=":/images/jj2.png";
113 | MapStytle[9]=":/images/m2.png";
114 | MapStytle[10]=":/images/w2.png";
115 | }
116 | void Drawer::initialfriendsList()
117 | {
118 | //qDebug()<<"initial List";
119 | int i;
120 | if(!friendList.isEmpty())
121 | {
122 | friendsListButtons=new QToolButton *[friendList.size()+10];
123 | for(i=0;i<(friendList.size()+10);i++)
124 | {
125 | //qDebug()<<"if i:"<setText(friendName);
135 | friendsListButtons[friendsNum]->setIcon(QPixmap(":/images/qq.png"));
136 | friendsListButtons[friendsNum]->setIconSize(QPixmap(":/images/qq.png").size());
137 | friendsListButtons[friendsNum]->setAutoRaise(true);
138 | friendsListButtons[friendsNum]->setEnabled(false);
139 | friendsListButtons[friendsNum]->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
140 | friLayout->addWidget(friendsListButtons[friendsNum]);
141 | friendsNum++;
142 | }
143 | checkOnlineState=new onlineState;
144 | onlineStateTimer->start(5000);
145 | }
146 | void Drawer::CheckonlineState()
147 | {
148 | if(checkOnlineState->StateUpdateDone)
149 | {
150 | users=checkOnlineState->users;
151 | int i,j;
152 | //qDebug()<<"--------------------friendsNum-----------------------"<text();
156 | //qDebug()<<"---friendName---"<count;j++)
158 | {
159 | if(checkOnlineState->users[j].name==friendName.toStdString())
160 | {
161 | if(checkOnlineState->users[j].online==1)
162 | {
163 | //friendsListButtons[i]->setText(friendName);
164 | friendsListButtons[i]->setEnabled(true);
165 | }
166 | else
167 | {
168 | friendsListButtons[i]->setEnabled(false);
169 | }
170 | friendsListButtons[i]->setIcon(QPixmap(MapStytle[checkOnlineState->users[j].pic]));
171 | friendsListButtons[i]->setIconSize(QPixmap(MapStytle[checkOnlineState->users[j].pic]).size());
172 | }
173 | if(checkOnlineState->users[j].name==username.toStdString())
174 | {
175 | //qDebug()<<"---Name---"<setIcon(QPixmap(MapStytle[checkOnlineState->users[j].pic]));
177 | toolBtn1->setIconSize(QPixmap(MapStytle[checkOnlineState->users[j].pic]).size());
178 | }
179 |
180 | }
181 |
182 | }
183 | checkOnlineState->StateUpdateDone=false;
184 | }
185 | //onlineStateTimer->stop();
186 | }
187 |
188 | void Drawer::MapStytleSet()
189 | {
190 | toolBtn1->setIcon(QPixmap(MapStytle[SelectMapStytle->currentIndex()]));
191 | toolBtn1->setIconSize(QPixmap(MapStytle[SelectMapStytle->currentIndex()]).size());
192 | PicChangeflag=true;
193 | }
194 |
195 | void Drawer::showChatWidget1()
196 | {
197 | chat1 = new TcpClient();
198 | chat1->username = toolBtn1->text();
199 | chat1->setWindowTitle(toolBtn1->text());
200 | chat1->show();
201 | }
202 | void Drawer::getFDL()
203 | {
204 | getFriendsList=new friendsList;
205 | getFriendsList->username=username;
206 | getFriendsList->sendRQ();
207 | getfdlTimer->stop();
208 | }
209 | void Drawer::CheckFlag()
210 | {
211 | if(getFriendsList->havedoneFlag)
212 | {
213 | friendList=getFriendsList->friendList;
214 | initialfriendsList();
215 | havedoneTimer->stop();
216 | //getFriendsList->havedoneFlag=false;
217 | }
218 | //qDebug()<<"checking..."<havedoneFlag;
219 | }
220 | void Drawer::slotAddFriends()
221 | {
222 | addFriends = new AddFriends();
223 | addFriends->username=username;
224 | addFriends->show();
225 |
226 | }
227 | void Drawer::showaddfriendWidget()
228 | {
229 | if(!changefunc)
230 | {
231 | toolBtn2->hide();
232 | QString msg;
233 | msg+=fromname+" want to add you as a friend,do you agree?";
234 | QMessageBox message(QMessageBox::Information,"addfriend request...",msg,QMessageBox::Yes|QMessageBox::No,this);
235 | if(message.exec()==QMessageBox::Yes)
236 | {
237 | addflag=true;
238 | int currNum=friendsNum;
239 | //qDebug()<<"fromname "<setText(fromname);
241 | friendsListButtons[currNum]->setIcon(QPixmap(":/images/qq.png"));
242 | friendsListButtons[currNum]->setIconSize(QPixmap(":/images/qq.png").size());
243 | friendsListButtons[currNum]->setAutoRaise(true);
244 | friendsListButtons[currNum]->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
245 | friLayout->addWidget(friendsListButtons[currNum]);
246 | friendsNum++;
247 | }
248 | else
249 | {
250 | refuseflag=true;
251 | }
252 | }
253 | else
254 | {
255 | toolBtn2->hide();
256 | QMessageBox::information(this, tr("the message from server..."), tr("your requet had been refused..."));
257 | }
258 | }
259 | //重写鼠标点击和移动事件,使没有边框的窗口可以通过鼠标移动
260 | void Drawer::mousePressEvent(QMouseEvent *event)
261 | {
262 | this->windowPos = this->pos(); // 获得部件当前位置
263 | this->mousePos = event->globalPos(); // 获得鼠标位置
264 | this->dPos = mousePos - windowPos; // 移动后部件所在的位置
265 | }
266 |
267 | void Drawer::mouseMoveEvent(QMouseEvent *event)
268 | {
269 | this->move(event->globalPos() - this->dPos);
270 | }
271 | void Drawer::Quit()
272 | {
273 | QMessageBox message(QMessageBox::Information,"退出客户端","是否退出?",QMessageBox::Yes|QMessageBox::No,this);
274 | message.setButtonText(QMessageBox::Yes, QString("确 定"));
275 | message.setButtonText(QMessageBox::No, QString("返 回"));
276 | if(message.exec()==QMessageBox::Yes)
277 | {
278 | qApp->quit();//退出当前应用程序,需要 QApplication的头文件
279 | }
280 | else
281 | {
282 | return;
283 | }
284 | }
285 |
--------------------------------------------------------------------------------
/chatRoom/drawer.h:
--------------------------------------------------------------------------------
1 | #ifndef DRAWER_H
2 | #define DRAWER_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include "tcpclient.h"
17 | #include "addfriends.h"
18 | #include "friendslist.h"
19 | #include "onlinestate.h"
20 | #include "command.h"
21 | class Drawer : public QToolBox
22 | {
23 | Q_OBJECT
24 | public:
25 | Drawer(QWidget *parent = 0, Qt::WindowFlags f = 0);
26 |
27 | QString username;
28 | QString fromname;
29 | QString toname;
30 | QString onlinename;
31 | QTabWidget *tabWidget;
32 | QToolButton *toolBtn1;
33 | QToolButton *toolBtn2;
34 | QPushButton *addFriendsBtn;
35 | QComboBox *SelectMapStytle;
36 | QWidget *myFriends;
37 | QVBoxLayout *friLayout;
38 | //QLabel *picSelect;
39 | bool addflag;
40 | bool refuseflag;
41 | bool changefunc;
42 | bool PicChangeflag;
43 | QQueue friendList;
44 | QTimer *havedoneTimer;
45 | QToolButton **friendsListButtons;
46 | int friendsNum;
47 | AddFriends *addFriends;
48 | private slots:
49 | void showChatWidget1();
50 | void slotAddFriends();
51 | void showaddfriendWidget();
52 | void MapStytleSet();
53 | void getFDL();
54 | void CheckFlag();
55 | void CheckonlineState();
56 | void Quit();
57 | private:
58 | QPoint windowPos;//窗口位置
59 | QPoint mousePos;//鼠标位置
60 | QPoint dPos;//鼠标移动后的位置
61 | void mousePressEvent(QMouseEvent *event);//鼠标按下事件(用于移动主界面)
62 | void mouseMoveEvent(QMouseEvent *event);//鼠标移动事件
63 | void initialMapstylestring();
64 | void initialfriendsList();
65 | QString MapStytle[11];
66 | TcpClient *chat1;
67 | friendsList *getFriendsList;
68 | onlineState *checkOnlineState;
69 | QTimer *getfdlTimer;
70 | QTimer *onlineStateTimer;
71 | struct userInfo *users;//有嫌疑
72 | };
73 |
74 | #endif // DRAWER_H
75 |
--------------------------------------------------------------------------------
/chatRoom/friendslist.cpp:
--------------------------------------------------------------------------------
1 | #include "friendslist.h"
2 |
3 | friendsList::friendsList(QWidget *parent) : QWidget(parent)
4 | {
5 | //连接服务器
6 | port = 12345;
7 | serverIP = new QHostAddress();
8 | QString ip = SERVER_IP;
9 | serverIP->setAddress(ip);
10 | tcpSocket=new QTcpSocket(this);
11 | tcpSocket->connectToHost(*serverIP, port);
12 | connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(dataReceived()));
13 | havedoneFlag=false;
14 | }
15 | friendsList::~friendsList()
16 | {
17 | tcpSocket->disconnectFromHost();
18 | }
19 | void friendsList::sendRQ()
20 | {
21 | QString msg = tr(FRIENDSLIST);
22 | msg+=username;
23 | int length=tcpSocket->write(msg.toLatin1(), msg.toLatin1().length());
24 | if(length != msg.toLatin1().length())
25 | {
26 | return;
27 | }
28 | }
29 | void friendsList::dataReceived()
30 | {
31 | QByteArray datagram;
32 | datagram.resize(tcpSocket->bytesAvailable());
33 | tcpSocket->read(datagram.data(), datagram.size());
34 | QString msg = datagram.data();
35 | //qDebug()<<"msg:"<disconnectFromHost();
53 | }
54 |
55 |
--------------------------------------------------------------------------------
/chatRoom/friendslist.h:
--------------------------------------------------------------------------------
1 | #ifndef FRIENDSLIST_H
2 | #define FRIENDSLIST_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include "command.h"
9 | class friendsList : public QWidget
10 | {
11 | Q_OBJECT
12 | public:
13 | explicit friendsList(QWidget *parent = 0);
14 | ~friendsList();
15 | void sendRQ();
16 | QString username;
17 | bool havedoneFlag;
18 | QQueue friendList;
19 | QTcpSocket *tcpSocket;
20 | private:
21 | int port;
22 | QHostAddress *serverIP;
23 | private slots:
24 | void dataReceived();
25 | };
26 |
27 | #endif // FRIENDSLIST_H
28 |
--------------------------------------------------------------------------------
/chatRoom/images.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | images/ChatRoom.jpg
4 | images/1.png
5 | images/qq.png
6 | images/w.png
7 | images/l.png
8 | images/z.png
9 | images/zz.png
10 | images/m.png
11 | images/boss.png
12 | images/jj.png
13 | images/jj2.png
14 | images/m2.png
15 | images/w2.png
16 |
17 |
18 |
--------------------------------------------------------------------------------
/chatRoom/images/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CXHGT/TCP-ChatRoom/99790ff02ae5bb040e525390561b8d769ec9415b/chatRoom/images/1.png
--------------------------------------------------------------------------------
/chatRoom/images/ChatRoom.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CXHGT/TCP-ChatRoom/99790ff02ae5bb040e525390561b8d769ec9415b/chatRoom/images/ChatRoom.jpg
--------------------------------------------------------------------------------
/chatRoom/images/Linux.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CXHGT/TCP-ChatRoom/99790ff02ae5bb040e525390561b8d769ec9415b/chatRoom/images/Linux.jpg
--------------------------------------------------------------------------------
/chatRoom/images/boss.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CXHGT/TCP-ChatRoom/99790ff02ae5bb040e525390561b8d769ec9415b/chatRoom/images/boss.png
--------------------------------------------------------------------------------
/chatRoom/images/jj.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CXHGT/TCP-ChatRoom/99790ff02ae5bb040e525390561b8d769ec9415b/chatRoom/images/jj.png
--------------------------------------------------------------------------------
/chatRoom/images/jj2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CXHGT/TCP-ChatRoom/99790ff02ae5bb040e525390561b8d769ec9415b/chatRoom/images/jj2.png
--------------------------------------------------------------------------------
/chatRoom/images/l.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CXHGT/TCP-ChatRoom/99790ff02ae5bb040e525390561b8d769ec9415b/chatRoom/images/l.png
--------------------------------------------------------------------------------
/chatRoom/images/liu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CXHGT/TCP-ChatRoom/99790ff02ae5bb040e525390561b8d769ec9415b/chatRoom/images/liu.png
--------------------------------------------------------------------------------
/chatRoom/images/m.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CXHGT/TCP-ChatRoom/99790ff02ae5bb040e525390561b8d769ec9415b/chatRoom/images/m.png
--------------------------------------------------------------------------------
/chatRoom/images/m2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CXHGT/TCP-ChatRoom/99790ff02ae5bb040e525390561b8d769ec9415b/chatRoom/images/m2.png
--------------------------------------------------------------------------------
/chatRoom/images/qq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CXHGT/TCP-ChatRoom/99790ff02ae5bb040e525390561b8d769ec9415b/chatRoom/images/qq.png
--------------------------------------------------------------------------------
/chatRoom/images/w.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CXHGT/TCP-ChatRoom/99790ff02ae5bb040e525390561b8d769ec9415b/chatRoom/images/w.png
--------------------------------------------------------------------------------
/chatRoom/images/w2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CXHGT/TCP-ChatRoom/99790ff02ae5bb040e525390561b8d769ec9415b/chatRoom/images/w2.png
--------------------------------------------------------------------------------
/chatRoom/images/z.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CXHGT/TCP-ChatRoom/99790ff02ae5bb040e525390561b8d769ec9415b/chatRoom/images/z.png
--------------------------------------------------------------------------------
/chatRoom/images/zz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CXHGT/TCP-ChatRoom/99790ff02ae5bb040e525390561b8d769ec9415b/chatRoom/images/zz.png
--------------------------------------------------------------------------------
/chatRoom/information.h:
--------------------------------------------------------------------------------
1 | #ifndef INFORMATION_H
2 | #define INFORMATION_H
3 |
4 | #include
5 |
6 | QString username;
7 |
8 | #endif // INFORMATION_H
9 |
--------------------------------------------------------------------------------
/chatRoom/main.cpp:
--------------------------------------------------------------------------------
1 | #include "sign.h"
2 | #include "drawer.h"
3 | #include
4 | #include
5 |
6 | int main(int argc, char *argv[])
7 | {
8 | QApplication a(argc, argv);
9 |
10 | Sign s;
11 | s.show();
12 |
13 | return a.exec();
14 | }
15 |
--------------------------------------------------------------------------------
/chatRoom/onlinestate.cpp:
--------------------------------------------------------------------------------
1 | #include "onlinestate.h"
2 |
3 | onlineState::onlineState(QWidget *parent) : QWidget(parent)
4 | {
5 | //连接服务器
6 | port = 12345;
7 | serverIP = new QHostAddress();
8 | QString ip = SERVER_IP;
9 | serverIP->setAddress(ip);
10 | tcpSocket=new QTcpSocket(this);
11 | tcpSocket->connectToHost(*serverIP, port);
12 | connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(dataReceived()));
13 | sendRQ();
14 | StateUpdateDone=false;
15 | SendRqTimer=new QTimer(this);
16 | connect(SendRqTimer,SIGNAL(timeout()),this,SLOT(senRq()));
17 | SendRqTimer->start(15000);
18 | }
19 | void onlineState::sendRQ()
20 | {
21 | QString msg = tr(ONLINESTATE);
22 | tcpSocket->write(msg.toLatin1(), msg.toLatin1().length());
23 | }
24 | void onlineState::senRq()
25 | {
26 | tcpSocket->connectToHost(*serverIP, port);
27 | sendRQ();
28 | }
29 | void onlineState::dataReceived()
30 | {
31 | QByteArray datagram;
32 | datagram.resize(tcpSocket->bytesAvailable());
33 | tcpSocket->read(datagram.data(), datagram.size());
34 | QString msg = datagram.data();
35 | //qDebug()<<"online State msg:"<disconnectFromHost();
53 | }
54 |
--------------------------------------------------------------------------------
/chatRoom/onlinestate.h:
--------------------------------------------------------------------------------
1 | #ifndef ONLINESTATE_H
2 | #define ONLINESTATE_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include "command.h"
10 | struct userInfo
11 | {
12 | std::string name;
13 | int online;
14 | int pic;
15 | };
16 | class onlineState : public QWidget
17 | {
18 | Q_OBJECT
19 | public:
20 | explicit onlineState(QWidget *parent = 0);
21 | void sendRQ();
22 | //QString username;
23 | QTimer *SendRqTimer;
24 | struct userInfo *users;
25 | int count;
26 | bool StateUpdateDone;
27 | private:
28 | int port;
29 | QHostAddress *serverIP;
30 | QTcpSocket *tcpSocket;
31 | private slots:
32 | void dataReceived();
33 | void senRq();
34 | };
35 |
36 | #endif // ONLINESTATE_H
37 |
--------------------------------------------------------------------------------
/chatRoom/sign.cpp:
--------------------------------------------------------------------------------
1 | #include "sign.h"
2 | #include "drawer.h"
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | Sign::Sign(QWidget *parent)
9 | : QDialog(parent)
10 | {
11 | setWindowTitle(tr("聊天室客户端"));
12 | this->setFixedSize(400,200);
13 |
14 | registerBtn = new QPushButton(tr("注册"));
15 | LogInBtn = new QPushButton(tr("登录"));
16 | connectBtn = new QPushButton(tr("连接服务器"));
17 | nameLabel = new QLabel(tr("Name(英文):"));
18 | passwordLabel = new QLabel(tr("Password:"));
19 | // ServerIPLabel=new QLabel(tr("ServerIP"));
20 | // ServerIPEdit=new QLineEdit();
21 | nameLineEdit = new QLineEdit();
22 | passwordLineEdit = new QLineEdit();
23 | passwordLineEdit->setEchoMode(QLineEdit::Password);
24 | tcpSocket = new QTcpSocket(this);
25 |
26 |
27 | mainLayout = new QGridLayout(this);
28 | mainLayout->addWidget(nameLabel, 0, 0);
29 | mainLayout->addWidget(nameLineEdit, 0, 1, 1, 2);
30 | mainLayout->addWidget(passwordLabel, 1, 0);
31 | mainLayout->addWidget(passwordLineEdit, 1, 1, 1, 2);
32 | // mainLayout->addWidget(ServerIPLabel, 2, 0);
33 | // mainLayout->addWidget(ServerIPEdit, 2, 1, 1, 2);
34 | mainLayout->addWidget(registerBtn, 2, 0);
35 | mainLayout->addWidget(LogInBtn, 2, 1);
36 | mainLayout->addWidget(connectBtn, 2, 2);
37 | //mainLayout->setContentsMargins(0,0,0,0);//让布局紧贴主窗口,不留空白
38 | //mainLayout->setSpacing(0);
39 |
40 | addfriendTimer=new QTimer(this);
41 | connect(addfriendTimer,SIGNAL(timeout()),this,SLOT(Checkflag()));
42 |
43 | PicChangeTimer=new QTimer(this);
44 | connect(PicChangeTimer,SIGNAL(timeout()),this,SLOT(CheckPicChange()));
45 |
46 | registerBtn->setEnabled(false);
47 | LogInBtn->setEnabled(false);
48 |
49 | connect(connectBtn, SIGNAL(clicked()), this, SLOT(slotConnect()));
50 | connect(registerBtn, SIGNAL(clicked()), this, SLOT(slotRegister()));
51 | connect(LogInBtn, SIGNAL(clicked()), this, SLOT(slotLogIn()));
52 | connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(dataReceived()));
53 | connect(tcpSocket, SIGNAL(connected()), this, SLOT(connected()));
54 | }
55 |
56 | Sign::~Sign()
57 | {
58 | tcpSocket->disconnectFromHost();
59 | }
60 | void Sign::slotConnect()
61 | {
62 | if(nameLineEdit->text() == "" || passwordLineEdit->text() == "")
63 | {
64 | QMessageBox::warning(this, tr("error"), tr("Name or Password is empty!"));
65 | return;
66 | }
67 |
68 | //连接服务器
69 | port = 12345;
70 | serverIP = new QHostAddress();
71 | QString ip = SERVER_IP;
72 | serverIP->setAddress(ip);
73 | tcpSocket->connectToHost(*serverIP, port);
74 | }
75 |
76 | void Sign::connected()
77 | {
78 | connectBtn->setEnabled(false);
79 | registerBtn->setEnabled(true);
80 | LogInBtn->setEnabled(true);
81 | }
82 |
83 |
84 | void Sign::slotRegister()
85 | {
86 | QString msg = tr(REGISTER);
87 | username = nameLineEdit->text();
88 | QString password = passwordLineEdit->text();
89 | msg += username + '\t' + password;
90 | int length = tcpSocket->write(msg.toLatin1(), msg.toLatin1().length());
91 | if(length != msg.toUtf8().length())
92 | {
93 | return;
94 | }
95 | }
96 |
97 | void Sign::slotLogIn()
98 | {
99 | QString msg = tr(LOGIN);
100 | username = nameLineEdit->text();
101 | QString password = passwordLineEdit->text();
102 | msg += username + '\t' + password;
103 | int length = tcpSocket->write(msg.toLatin1(), msg.toLatin1().length());
104 | if(length != msg.toUtf8().length())
105 | {
106 | return;
107 | }
108 | }
109 |
110 | void Sign::dataReceived()
111 | {
112 | QByteArray datagram;
113 | datagram.resize(tcpSocket->bytesAvailable());
114 | tcpSocket->read(datagram.data(), datagram.size());
115 | QString msg = datagram.data();
116 |
117 | //qDebug()<<"msg [0]:"<hide();
123 |
124 | drawer = new Drawer();
125 | drawer->toolBtn1->setText(username);
126 | drawer->username=username;
127 | //drawer->resize(250, 500);
128 | drawer->setFixedSize(250,500);
129 | drawer->show();
130 | PicChangeTimer->start(2000);
131 | }
132 | else if(msg == "REGISTER SUCCESS")
133 | {
134 | QMessageBox::information(this, tr("register success, now you can log in"), tr("register success, now you can log in"));
135 | }
136 | else if(msg.contains("*AdDR.",Qt::CaseSensitive))
137 | {
138 | std::string rec=msg.toStdString();
139 | auto it = rec.find('+');
140 | //qDebug()<<"it "<fromname=fromname;
146 | drawer->toname=toname;
147 | drawer->toolBtn2->show();
148 | addfriendTimer->start(10);
149 | }
150 | else if(msg=="your requet had been refused...")
151 | {
152 | drawer->toolBtn2->show();
153 | drawer->changefunc=true;
154 | }
155 | else if(msg.contains("*ACCEPT.",Qt::CaseSensitive))
156 | {
157 | int currNum=drawer->friendsNum;
158 | qDebug()<<"toname:"<addFriends->toname;
159 | drawer->friendsListButtons[currNum]->setText(drawer->addFriends->toname);
160 | drawer->friendsListButtons[currNum]->setIcon(QPixmap(":/images/qq.png"));
161 | drawer->friendsListButtons[currNum]->setIconSize(QPixmap(":/images/qq.png").size());
162 | drawer->friendsListButtons[currNum]->setAutoRaise(true);
163 | drawer-> friendsListButtons[currNum]->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
164 | drawer->friLayout->addWidget(drawer->friendsListButtons[currNum]);
165 | drawer->friendsNum++;
166 | }
167 | else if(msg=="The name has been registered")
168 | {
169 | QMessageBox::information(this, tr("The name has been registered"), tr("The name has been registered"));
170 | }
171 | else if(msg=="You have to register first")
172 | {
173 | QMessageBox::information(this, tr("You have to register first"), tr("You have to register first"));
174 | }
175 | else if(msg=="password is wrong")
176 | {
177 | QMessageBox::information(this, tr("password is wrong"), tr("password is wrong"));
178 | }
179 | // else if(msg.contains("*ONLINE.",Qt::CaseSensitive))
180 | // {
181 | // qDebug()<<"msg :"<onlinename=onlineName;
188 | // drawer->onlineTimer->start(500);
189 | // }
190 | }
191 | void Sign::Checkflag()
192 | {
193 | if(drawer->addflag)
194 | {
195 | QString msg = tr(ACCEPT);
196 | msg+=fromname+"\t"+toname+" have been friends";
197 | int length=0;
198 | if((length = tcpSocket->write(msg.toLatin1(),msg.toLatin1(). length())) != msg.toLatin1().length())
199 | {
200 | return;
201 | }
202 | addfriendTimer->stop();
203 | fromname.clear();
204 | //toname.clear();
205 | drawer->addflag=false;
206 | }
207 | if(drawer->refuseflag)
208 | {
209 | QString msg = tr(REFUSE);
210 | msg+=fromname;
211 | int length=0;
212 | if((length = tcpSocket->write(msg.toLatin1(),msg.toLatin1(). length())) != msg.toLatin1().length())
213 | {
214 | return;
215 | }
216 | addfriendTimer->stop();
217 | fromname.clear();
218 | toname.clear();
219 | drawer->refuseflag=false;
220 | }
221 | }
222 | void Sign::CheckPicChange()
223 | {
224 | if(drawer->PicChangeflag)
225 | {
226 | QString msg = tr(PICCHANGE);
227 | QString pic=QString::number(drawer->SelectMapStytle->currentIndex(),10);
228 | msg+=drawer->username+":"+pic;
229 | tcpSocket->write(msg.toLatin1(),msg.toLatin1(). length());
230 | drawer->PicChangeflag=false;
231 | }
232 |
233 | }
234 |
--------------------------------------------------------------------------------
/chatRoom/sign.h:
--------------------------------------------------------------------------------
1 | #ifndef SIGN_H
2 | #define SIGN_H
3 |
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include "command.h"
16 | #include "drawer.h"
17 |
18 | class Sign : public QDialog
19 | {
20 | Q_OBJECT
21 |
22 | public:
23 | Sign(QWidget *parent = 0);
24 | ~Sign();
25 |
26 | private:
27 | QGridLayout *mainLayout;
28 | QLabel *nameLabel;
29 | QLabel *passwordLabel;
30 | QPushButton *connectBtn;
31 | QLineEdit *nameLineEdit;
32 | QLineEdit *passwordLineEdit;
33 | QPushButton *registerBtn;
34 | QPushButton *LogInBtn;
35 | QTimer *addfriendTimer;
36 | QString fromname;
37 | QString toname;
38 | int port;
39 | QHostAddress *serverIP;
40 | QTcpSocket *tcpSocket;
41 |
42 | QString username;
43 | Drawer *drawer;
44 | QTimer *PicChangeTimer;
45 | public slots:
46 | void slotRegister();
47 | void slotLogIn();
48 | void slotConnect();
49 | void dataReceived();
50 | void connected();
51 | void Checkflag();
52 | void CheckPicChange();
53 | };
54 |
55 | #endif // SIGN_H
56 |
--------------------------------------------------------------------------------
/chatRoom/tcpclient.cpp:
--------------------------------------------------------------------------------
1 | #include "tcpclient.h"
2 | #include
3 | #include
4 |
5 | TcpClient::TcpClient(QWidget *parent,Qt::WindowFlags f)
6 | : QDialog(parent,f)
7 | {
8 | setWindowTitle(tr("TCP Client"));
9 | resize(500, 300);
10 | contentListWidget = new QListWidget;
11 | sendLineEdit = new QLineEdit;
12 | sendBtn = new QPushButton(tr("Send"));
13 | clearBtn = new QPushButton(tr("Clear"));
14 | mainLayout = new QGridLayout(this);
15 | mainLayout->addWidget(contentListWidget,0,0,1,3);
16 | mainLayout->addWidget(sendLineEdit,1,0);
17 | mainLayout->addWidget(sendBtn,1,1);
18 | mainLayout->addWidget(clearBtn,1,2);
19 | port = 12345;
20 | IP = SERVER_IP;
21 | serverIP = new QHostAddress();
22 | connect(sendBtn,SIGNAL(clicked()),this,SLOT(slotSend()));
23 | connect(clearBtn,SIGNAL(clicked()),this,SLOT(slotClear()));
24 |
25 | if(!serverIP->setAddress(IP))
26 | {
27 | QMessageBox::information(this,tr("error"),tr("server ip address error!"));
28 | return;
29 | }
30 | /* 创建了一个QTcpSocket类对象,并将信号/槽连接起来 */
31 | tcpSocket = new QTcpSocket(this);
32 | connect(tcpSocket,SIGNAL(connected()),this,SLOT (slotConnected()));
33 | connect(tcpSocket,SIGNAL(readyRead()),this,SLOT (dataReceived()));
34 | tcpSocket->connectToHost(*serverIP ,port);
35 | }
36 |
37 | TcpClient::~TcpClient()
38 | {
39 |
40 | }
41 | //在关闭窗口之前,断开与服务器的连接
42 | void TcpClient::closeEvent(QCloseEvent *event)
43 | {
44 | tcpSocket->disconnectFromHost();
45 | tcpSocket->waitForDisconnected();
46 | event->accept();
47 | }
48 |
49 | void TcpClient::slotConnected()
50 | {
51 | sendBtn->setEnabled(true);
52 | int length=0;
53 | QString msg = tr(MESSAGE);
54 | msg += username + ": Enter Chat Room";
55 | if((length = tcpSocket->write(msg.toLatin1(),msg.toLatin1(). length())) != msg.toLatin1().length())
56 | {
57 | return;
58 | }
59 | }
60 |
61 | void TcpClient::slotSend()
62 | {
63 | // QTextCodec::setCodecForTr( QTextCodec::codecForLocale() );
64 | // QTextCodec::setCodecForCStrings( QTextCodec::codecForLocale() );
65 | //QTextCodec *code= QTextCodec::codecForName("UTF-8");
66 | //QString strtest = "你好Test";
67 | //QByteArray bytest = code->fromUnicode( strtest );
68 |
69 | if(sendLineEdit->text() == "")
70 | {
71 | return;
72 | }
73 | QString msg = tr(MESSAGE);
74 | msg += username + ": " + sendLineEdit->text();
75 | //qDebug()<write(msg.toUtf8(), msg.toUtf8().length());//发送的数据转换为utf-8格式(网络字节序,中文也能识别)
77 | //qDebug()<<"have writen!";
78 | sendLineEdit->clear();
79 | }
80 |
81 | void TcpClient::slotClear()
82 | {
83 | contentListWidget->clear();
84 | }
85 |
86 | void TcpClient::dataReceived()
87 | {
88 | while(tcpSocket->bytesAvailable() > 0)
89 | {
90 | QByteArray datagram;
91 | datagram.resize(tcpSocket->bytesAvailable());
92 | tcpSocket->read(datagram.data(),datagram.size());
93 | QString msg = datagram.data();
94 | contentListWidget->addItem(msg.left(datagram.size()));
95 | contentListWidget->scrollToBottom();
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/chatRoom/tcpclient.h:
--------------------------------------------------------------------------------
1 | #ifndef TCPCLIENT_H
2 | #define TCPCLIENT_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include "command.h"
15 | class TcpClient : public QDialog
16 | {
17 | Q_OBJECT
18 |
19 | public:
20 | TcpClient(QWidget *parent = 0,Qt::WindowFlags f=0);
21 | ~TcpClient();
22 | QString username;
23 |
24 | private:
25 | QListWidget *contentListWidget;
26 | QLineEdit *sendLineEdit;
27 | QPushButton *sendBtn;
28 | QPushButton *clearBtn;
29 | QGridLayout *mainLayout;
30 | int port;
31 | QString IP;
32 | QHostAddress *serverIP;
33 | QTcpSocket *tcpSocket;
34 | void closeEvent(QCloseEvent *event);//关闭事件
35 | public slots:
36 | void slotConnected();
37 | void dataReceived();
38 | void slotSend();
39 | void slotClear();
40 | };
41 |
42 | #endif // TCPCLIENT_H
43 |
--------------------------------------------------------------------------------
/chatRoom/widget.cpp:
--------------------------------------------------------------------------------
1 | #include "widget.h"
2 | #include "ui_widget.h"
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | Widget::Widget(QWidget *parent, QString usrname) :
12 | QWidget(parent),
13 | ui(new Ui::Widget)
14 | {
15 | ui->setupUi(this);
16 | uName = usrname;
17 | port = 12345;
18 | udpSocket = new QUdpSocket(this);
19 | udpSocket->bind(port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
20 | connect(udpSocket, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams()));
21 | connect(ui->sendBtn, SIGNAL(clicked()), this, SLOT(on_sendBtn_clicked()));
22 | sndMsg(UsrEnter);
23 | }
24 |
25 | Widget::~Widget()
26 | {
27 | delete ui;
28 | }
29 |
30 |
31 | void Widget::sndMsg(MsgType type, QString srvaddr)
32 | {
33 | QByteArray data;
34 | QDataStream out(&data, QIODevice::WriteOnly);
35 | QString address = getIP();
36 | out << type << getUsr();
37 | switch(type)
38 | {
39 | case Msg:
40 | if(ui->msgTxtEdit->toPlainText() == "")
41 | {
42 | return;
43 | }
44 | out << address << getMsg();
45 | ui->msgBrowser->verticalScrollBar()->setValue(ui->msgBrowser->verticalScrollBar()->maximum());
46 | break;
47 | case UsrEnter:
48 | out << address;
49 | break;
50 | case UsrLeft:
51 | break;
52 | case FileName: {
53 | break;
54 | }
55 | case Refuse:
56 | break;
57 | }
58 |
59 | udpSocket->writeDatagram(data, data.length(), QHostAddress::Broadcast, port);
60 | }
61 |
62 |
63 | void Widget::processPendingDatagrams()
64 | {
65 | while(udpSocket->hasPendingDatagrams())
66 | {
67 | QByteArray datagram;
68 | //获取当前可供读取的UDP报文大小,并据此大小分配接收缓冲区
69 | datagram.resize(udpSocket->pendingDatagramSize());
70 |
71 | udpSocket->readDatagram(datagram.data(), datagram.size());
72 | QDataStream in(&datagram, QIODevice::ReadOnly);
73 | int msgType;
74 | in >> msgType;
75 | QString usrName, ipAddr, msg;
76 | QString time = QDateTime::currentDateTime().toString("yyy-MM-dd hh:mm:ss");
77 |
78 | switch(msgType)
79 | {
80 | case Msg:
81 | in >> usrName >> ipAddr >> msg;
82 | ui->msgBrowser->setTextColor(Qt::blue);
83 | ui->msgBrowser->setCurrentFont(QFont("Times New Roman", 12));
84 | ui->msgBrowser->append(" [ " + usrName + " ] " + time);
85 | ui->msgBrowser->append(msg);
86 | break;
87 | case UsrEnter:
88 | in >> usrName >> ipAddr;
89 | usrEnter(usrName, ipAddr);
90 | break;
91 | case UsrLeft:
92 | in >> usrName;
93 | usrLeft(usrName, time);
94 | break;
95 | case FileName: {
96 | break;
97 | }
98 | case Refuse:
99 | break;
100 | }
101 | }
102 | }
103 |
104 | void Widget::usrEnter(QString usrname, QString ipaddr)
105 | {
106 | //判断是否已经在用户列表中
107 | bool isEmpty = ui->usrTblWidget->findItems(usrname, Qt::MatchExactly).isEmpty();
108 | if(isEmpty)
109 | {
110 | QTableWidgetItem *usr = new QTableWidgetItem(usrname);
111 | QTableWidgetItem *ip = new QTableWidgetItem(ipaddr);
112 | ui->usrTblWidget->insertRow(0);
113 | ui->usrTblWidget->setItem(0, 0, usr);
114 | ui->usrTblWidget->setItem(0, 1, ip);
115 | ui->msgBrowser->setTextColor(Qt::gray);
116 | ui->msgBrowser->setCurrentFont(QFont("Times New Roman", 10));
117 | ui->msgBrowser->append(tr("%1 online").arg(usrname));
118 | ui->usrNumLbl->setText(tr("%1 online people").arg(ui->usrTblWidget->rowCount()));
119 | sndMsg(UsrEnter);
120 | }
121 | }
122 |
123 | void Widget::usrLeft(QString usrname, QString time)
124 | {
125 | int rowNum = ui->usrTblWidget->findItems(usrname, Qt::MatchExactly).first()->row();
126 | ui->usrTblWidget->removeRow(rowNum);
127 | ui->msgBrowser->setTextColor(Qt::gray);
128 | ui->msgBrowser->setCurrentFont(QFont("Times New Roman", 10));
129 | ui->msgBrowser->append(tr("%1 left at %2").arg(usrname).arg(time));
130 | ui->usrNumLbl->setText(tr("%1 online people").arg(ui->usrTblWidget->rowCount()));
131 | }
132 |
133 |
134 | QString Widget::getIP()
135 | {
136 | QList list = QNetworkInterface::allAddresses();
137 | foreach (QHostAddress addr, list) {
138 | if(addr.protocol() == QAbstractSocket::IPv4Protocol)
139 | return addr.toString();
140 | }
141 | return 0;
142 | }
143 |
144 | QString Widget::getUsr()
145 | {
146 | return uName;
147 | }
148 |
149 | QString Widget::getMsg()
150 | {
151 | QString msg = ui->msgTxtEdit->toHtml();
152 | ui->msgTxtEdit->clear();
153 | ui->msgTxtEdit->setFocus();
154 | return msg;
155 | }
156 |
157 | void Widget::on_sendBtn_clicked()
158 | {
159 | sndMsg(Msg);
160 | }
161 |
162 | void Widget::on_exitBtn_clicked()
163 | {
164 | close();
165 | }
166 |
--------------------------------------------------------------------------------
/chatRoom/widget.h:
--------------------------------------------------------------------------------
1 | #ifndef WIDGET_H
2 | #define WIDGET_H
3 |
4 | #include
5 | #include "command.h"
6 |
7 | class QUdpSocket;
8 |
9 | namespace Ui {
10 | class Widget;
11 | }
12 |
13 | class Widget : public QWidget
14 | {
15 | Q_OBJECT
16 |
17 | public:
18 | explicit Widget(QWidget *parent, QString usrname);
19 | ~Widget();
20 |
21 | protected:
22 | void usrEnter(QString, QString);
23 | void usrLeft(QString, QString);
24 | void sndMsg(MsgType type, QString srvaddr = "");
25 | QString getIP();
26 | QString getMsg();
27 | QString getUsr();
28 |
29 | private:
30 | Ui::Widget *ui;
31 |
32 | QUdpSocket *udpSocket;
33 | qint16 port;
34 | QString uName;
35 |
36 | private slots:
37 | void processPendingDatagrams();
38 | void on_sendBtn_clicked();
39 | void on_exitBtn_clicked();
40 | };
41 |
42 | #endif // WIDGET_H
43 |
--------------------------------------------------------------------------------
/chatRoom/widget.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | Widget
4 |
5 |
6 |
7 | 0
8 | 0
9 | 780
10 | 450
11 |
12 |
13 |
14 | Form
15 |
16 |
17 |
18 |
19 | 5
20 | 11
21 | 541
22 | 231
23 |
24 |
25 |
26 |
27 |
28 |
29 | 3
30 | 280
31 | 541
32 | 131
33 |
34 |
35 |
36 |
37 |
38 |
39 | 555
40 | 11
41 | 221
42 | 401
43 |
44 |
45 |
46 | QAbstractItemView::SingleSelection
47 |
48 |
49 | QAbstractItemView::SelectRows
50 |
51 |
52 |
53 | 新建列
54 |
55 |
56 |
57 |
58 | ipAddress
59 |
60 |
61 |
62 |
63 |
64 |
65 | 0
66 | 250
67 | 213
68 | 22
69 |
70 |
71 |
72 |
73 |
74 |
75 | 230
76 | 250
77 | 69
78 | 22
79 |
80 |
81 |
82 | 4
83 |
84 | -
85 |
86 | 8
87 |
88 |
89 | -
90 |
91 | 9
92 |
93 |
94 | -
95 |
96 | 10
97 |
98 |
99 | -
100 |
101 | 11
102 |
103 |
104 | -
105 |
106 | 12
107 |
108 |
109 | -
110 |
111 | 13
112 |
113 |
114 | -
115 |
116 | 14
117 |
118 |
119 | -
120 |
121 | 15
122 |
123 |
124 | -
125 |
126 | 16
127 |
128 |
129 | -
130 |
131 | 17
132 |
133 |
134 | -
135 |
136 | 18
137 |
138 |
139 | -
140 |
141 | 19
142 |
143 |
144 | -
145 |
146 | 20
147 |
148 |
149 | -
150 |
151 | 21
152 |
153 |
154 | -
155 |
156 | 22
157 |
158 |
159 |
160 |
161 |
162 |
163 | 460
164 | 420
165 | 75
166 | 23
167 |
168 |
169 |
170 | Send
171 |
172 |
173 |
174 |
175 |
176 | 560
177 | 420
178 | 75
179 | 23
180 |
181 |
182 |
183 | Exit
184 |
185 |
186 |
187 |
188 |
189 | 660
190 | 420
191 | 91
192 | 20
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
--------------------------------------------------------------------------------
/server_mysql/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | g++ -g -Wall -std=c++11 -I /usr/include/mysql -I /usr/include/ -o main main.cpp MyReactor.cpp -pthread -lmysqlclient
3 |
4 | clean:
5 | rm -rf main
6 |
--------------------------------------------------------------------------------
/server_mysql/MyReactor.cpp:
--------------------------------------------------------------------------------
1 | #include "MyReactor.h"
2 |
3 | #include "spdlog/sinks/daily_file_sink.h"
4 | #include "spdlog/sinks/basic_file_sink.h"
5 | auto my_logger = spdlog::stdout_color_mt("my_logger");//日志输出到屏幕
6 |
7 | MyReactor::MyReactor()
8 | {
9 | }
10 |
11 | MyReactor::~MyReactor()
12 | {
13 | }
14 |
15 | struct ARG//定义结构体,用于传递this指针参数
16 | {
17 | MyReactor* pThis;
18 | };
19 | //服务器功能初始化,完成数据库的连接,服务器的初始化,accept线程、广播线程、主工作线程的创建
20 | bool MyReactor::init(const char* ip, short nport)
21 | {
22 | //连接数据库
23 | int ret = connect();
24 | if(ret == -1)
25 | {
26 | my_logger->error("mysql connection failed");
27 | }
28 |
29 |
30 | if(!create_server_listener(ip, nport))//create_server_listener 初始化监听请求
31 | {
32 | my_logger->error("Unable to bind: {0}:{1}.", ip, nport);
33 | return false;
34 | }
35 |
36 | ARG *arg = new ARG();
37 | arg->pThis = this;
38 |
39 | pthread_create(&m_accept_threadid, NULL, accept_thread_proc, (void*)arg);//accept线程,接收监听请求并将请求挂到epoll监听树上
40 |
41 | pthread_create(&m_send_threadid, NULL, send_thread_proc, (void*)arg);//用于向所有连接到服务器的客户端广播消息的线程
42 |
43 | for(int i = 0; i < WORKER_THREAD_NUM; i++)
44 | {
45 | pthread_create(&m_threadid[i], NULL, worker_thread_proc, (void*)arg);
46 | }
47 |
48 | return true;
49 | }
50 |
51 | //关闭服务器
52 | bool MyReactor::uninit()
53 | {
54 | m_bStop = true;
55 |
56 | /* 将读端和写端都关闭 */
57 | shutdown(m_listenfd, SHUT_RDWR);
58 | close(m_listenfd);
59 | close(m_epollfd);
60 |
61 | mysql_close(mysql);
62 |
63 | return true;
64 | }
65 |
66 | //epoll监听结果线程
67 | void* MyReactor::main_loop(void *p)
68 | {
69 | my_logger->info("main thread id = {}", pthread_self());
70 |
71 | MyReactor* pReactor = static_cast(p);
72 |
73 | while(!pReactor->m_bStop)
74 | {
75 | struct epoll_event ev[1024];
76 | int n = epoll_wait(pReactor->m_epollfd, ev, 1024, 10);//10代表阻塞等待10ms,每次循环都等待10ms,超时后直接返回0
77 | if(n == 0)
78 | continue;
79 | else if(n < 0)
80 | {
81 | my_logger->error("epoll_wait error");
82 | continue;
83 | }
84 |
85 | int m = std::min(n, 1024);
86 | for(int i = 0; i < m; i++)
87 | {
88 | /* 有新连接 */
89 | if(ev[i].data.fd == pReactor->m_listenfd)
90 | pthread_cond_signal(&pReactor->m_accept_cond);//唤醒accept线程
91 | /* 有数据 */
92 | else
93 | {
94 | pthread_mutex_lock(&pReactor->m_client_mutex);
95 | pReactor->m_clientlist.push_back(ev[i].data.fd);
96 | pthread_mutex_unlock(&pReactor->m_client_mutex);
97 | pthread_cond_signal(&pReactor->m_client_cond);
98 | }
99 | }
100 | }
101 |
102 | my_logger->info("main loop exit ...");
103 | return NULL;
104 | }
105 |
106 | //关闭客户端封装函数(将客户端的描述符从epoll的监听树上摘下,再关闭客户端的描述符)
107 | bool MyReactor::close_client(int clientfd)
108 | {
109 | if(epoll_ctl(m_epollfd, EPOLL_CTL_DEL, clientfd, NULL) == -1)
110 | {
111 | my_logger->warn("release client socket failed as call epoll_ctl fail");
112 | }
113 |
114 | close(clientfd);
115 | return true;
116 | }
117 |
118 | //完成服务器的初始化,绑定,监听
119 | bool MyReactor::create_server_listener(const char* ip, short port)
120 | {
121 | m_listenfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
122 | if(m_listenfd == -1)
123 | {
124 | my_logger->error("fail to create a socket");
125 | return false;
126 | }
127 |
128 | //设置服务器端口复用
129 | int on = 1;
130 | setsockopt(m_listenfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
131 | setsockopt(m_listenfd, SOL_SOCKET, SO_REUSEPORT, (char *)&on, sizeof(on));
132 |
133 | struct sockaddr_in servaddr;
134 | memset(&servaddr, 0, sizeof(servaddr));
135 | servaddr.sin_family = AF_INET;
136 | servaddr.sin_addr.s_addr = inet_addr(ip);
137 | servaddr.sin_port = htons(port);
138 |
139 | if(bind(m_listenfd, (sockaddr *)&servaddr, sizeof(servaddr)) == -1)//绑定服务器
140 | return false;
141 |
142 | if(listen(m_listenfd, 50) == -1)//设置监听
143 | return false;
144 |
145 | m_epollfd = epoll_create(1);//创建epoll句柄,设置监听数量
146 | if(m_epollfd == -1)
147 | return false;
148 |
149 | struct epoll_event e;
150 | memset(&e, 0, sizeof(e));
151 | e.events = EPOLLIN | EPOLLRDHUP;//EPOLLIN: 表示对应的文件描述符可以读(包括对端SOCKET正常关闭) EPOLLHUP:表示对应的文件描述符被挂断;
152 | e.data.fd = m_listenfd;
153 | if(epoll_ctl(m_epollfd, EPOLL_CTL_ADD, m_listenfd, &e) == -1)//向监听树中添加监听描述符
154 | return false;
155 |
156 | return true;
157 | }
158 |
159 | //等待epoll监听结果,若有新的连接请求,将其设置为非阻塞模式,并添加到epoll的监听树上
160 | void* MyReactor::accept_thread_proc(void* args)
161 | {
162 | ARG *arg = (ARG*)args;
163 | MyReactor* pReactor = arg->pThis;//获取this指针
164 |
165 | while(!pReactor->m_bStop)
166 | {
167 | pthread_mutex_lock(&pReactor->m_accept_mutex);//加锁
168 | pthread_cond_wait(&pReactor->m_accept_cond, &pReactor->m_accept_mutex);
169 | //阻塞等待条件变量m_accept_cond,同时释放互斥锁m_accept_mutex
170 | //当条件变量满足,线程被唤醒,同时重新加锁
171 |
172 | struct sockaddr_in clientaddr;
173 | socklen_t addrlen;
174 | int newfd = accept(pReactor->m_listenfd, (struct sockaddr *)&clientaddr, &addrlen);
175 | pthread_mutex_unlock(&pReactor->m_accept_mutex);
176 | if(newfd == -1)
177 | continue;
178 |
179 |
180 | pthread_mutex_lock(&pReactor->m_cli_mutex);
181 | pReactor->m_fds.insert(newfd);
182 | pthread_mutex_unlock(&pReactor->m_cli_mutex);
183 |
184 | my_logger->info("new client connected:");
185 | std::cout<error("fcntl error, oldflag = {0}, newflag = {1}", oldflag, newflag);
193 | continue;
194 | }
195 |
196 | struct epoll_event e;
197 | memset(&e, 0, sizeof(e));
198 | e.events = EPOLLIN | EPOLLRDHUP | EPOLLET;//EPOLLET epoll以水平触发模式工作,配合O_NONBLOCK使用,高效
199 | e.data.fd = newfd;
200 | /* 添加进epoll的兴趣列表 */
201 | if(epoll_ctl(pReactor->m_epollfd, EPOLL_CTL_ADD, newfd, &e) == -1)
202 | {
203 | my_logger->error("epoll_ctl error, fd = {}", newfd);
204 | }
205 | }
206 |
207 | return NULL;
208 | }
209 |
210 | //接收客户端消息,并完成用户数据与数据库的连接,对用户信息直接发送给客户端(不广播),对用户消息封装后交给广播线程
211 | void* MyReactor::worker_thread_proc(void* args)
212 | {
213 | ARG *arg = (ARG*)args;
214 | MyReactor* pReactor = arg->pThis;
215 |
216 | while(!pReactor->m_bStop)
217 | {
218 | int clientfd;
219 | pthread_mutex_lock(&pReactor->m_client_mutex);
220 | /* 注意!要用while循环等待 */
221 | while(pReactor->m_clientlist.empty())
222 | pthread_cond_wait(&pReactor->m_client_cond, &pReactor->m_client_mutex);
223 |
224 | /* 取出客户套接字 */
225 | clientfd = pReactor->m_clientlist.front();
226 | pReactor->m_clientlist.pop_front();
227 | pthread_mutex_unlock(&pReactor->m_client_mutex);
228 |
229 |
230 | //std::cout <<"run1..."<error("recv error, client disconnected, fd = {}", clientfd);
254 | pReactor->close_client(clientfd);
255 | bError = true;
256 | break;
257 | }
258 | }
259 | /* 对端关闭了socket,这端i也关闭 */
260 | else if(nRecv == 0)
261 | {
262 | /* 将该客户从accept后的客户列表中删除(从epoll的监听树上删除) */
263 | pthread_mutex_lock(&pReactor->m_cli_mutex);
264 | pReactor->m_fds.erase(clientfd);
265 | pthread_mutex_unlock(&pReactor->m_cli_mutex);
266 | char query[100];
267 | int ret;
268 | pthread_mutex_lock(&pReactor->m_clie_name);
269 | std::cout<<"this clientfd:"<sqlQuery(query);
272 | if(ret==-1)
273 | {
274 | my_logger->error("select clientfd error:{}",mysql_error(pReactor->mysql));
275 | }
276 | pReactor->res_ptr=mysql_store_result(pReactor->mysql);
277 | char name[20];
278 | std::string tempstr;
279 | if(!pReactor->m_clientname.empty())
280 | {
281 | while((pReactor->sqlrow=mysql_fetch_row(pReactor->res_ptr)))
282 | {
283 | //std::cout<<"search name:"<sqlrow[0]<::iterator it;
285 | for(it=pReactor->m_clientname.begin();
286 | it!=pReactor->m_clientname.end();it++)
287 | {
288 | //std::cout<<"*it:"<<*it<sqlrow[0])
290 | {
291 | tempstr=*it;
292 | strcpy(name,(*it).c_str());
293 | std::cout<<"username:"<res_ptr);
296 | sprintf(query,"select online from UserInfo where username='%s'",name);
297 | ret=pReactor->sqlQuery(query);
298 | if(ret==-1)
299 | {
300 | my_logger->error("select online error:{}",mysql_error(pReactor->mysql));
301 | }
302 | pReactor->res_ptr=mysql_store_result(pReactor->mysql);
303 | pReactor->sqlrow=mysql_fetch_row(pReactor->res_ptr);
304 | if(atoi(pReactor->sqlrow[0])==1)
305 | {
306 | memset(query,0,sizeof(query));
307 | sprintf(query,"update UserInfo set online=%d where username='%s'",0,name);
308 | int ret=pReactor->sqlQuery(query);
309 | if(ret==-1)
310 | {
311 | my_logger->error("update online error:{}",mysql_error(pReactor->mysql));
312 | }
313 | pReactor->m_clientname.remove(tempstr);
314 | tempstr.clear();
315 | break;
316 | }
317 | }
318 | }
319 | }
320 | }
321 | mysql_free_result(pReactor->res_ptr);
322 | my_logger->info("peer closed, client disconnected, fd = {}", clientfd);
323 | pReactor->close_client(clientfd);
324 | //std::cout<<"close over"<m_clie_name);
327 | break;
328 | }
329 |
330 | //注册
331 | if(buff[0] == REGISTER)
332 | {
333 | //std::cout<<"buff:"<sqlQuery(query);
354 | //std::cout<<"after query,ret= "<res_ptr = mysql_store_result(pReactor->mysql); //即使不需要返回值也要这样,否则会出错
357 | pReactor->sqlrow = mysql_fetch_row(pReactor->res_ptr);
358 | if(pReactor->sqlrow)
359 | {
360 | //my_logger->error("select error {}", mysql_error(pReactor->mysql));
361 | strclientmsg += "The name has been registered";
362 | }
363 | else
364 | {
365 | memset(query, 0, sizeof(query));
366 | //std::cout<<"clientfd: "<sqlQuery(query);
370 | if(ret == -1)
371 | {
372 | my_logger->error("insert error {}", mysql_error(pReactor->mysql));
373 | }
374 | else
375 | {
376 | //注册成功
377 | //新建一个用户表,用于保存用户信息
378 | memset(query, 0, sizeof(query));
379 | sprintf(query, "create table %s (friends char(30));",name);
380 | //std::cout<<"query3: "<sqlQuery(query);
382 | if(ret==-1)
383 | {
384 | my_logger->error("create table error:{}",mysql_error(pReactor->mysql));
385 | }
386 | //把自己加入到好友表中
387 | memset(query, 0, sizeof(query));
388 | sprintf(query, "insert into %s values('%s')", name, name);
389 | ret=pReactor->sqlQuery(query);
390 | if(ret==-1)
391 | {
392 | my_logger->error("inserr error:{}",mysql_error(pReactor->mysql));
393 | }
394 | strclientmsg += "REGISTER SUCCESS";
395 | // continue;
396 | if(mysql_errno(pReactor->mysql))
397 | {
398 | my_logger->error("retrive error {}", mysql_error(pReactor->mysql));
399 | }
400 | }
401 | }
402 | mysql_free_result(pReactor->res_ptr);
403 | }
404 | //登录
405 | else if(buff[0] == LOGIN)
406 | {
407 | std::string rec(buff);
408 | auto it = rec.find('\t');
409 | char name[20];
410 | strcpy(name,rec.substr(1,it-1).c_str());
411 | std::string str(name);
412 | char password[30];
413 | strcpy(password,rec.substr(it+1, rec.size()-1).c_str());
414 |
415 | char query[100];
416 | sprintf(query, "select password from UserInfo where username = '%s'",name);
417 | pReactor->sqlQuery(query);
418 | /* std::cout << "ret = " << ret << std::endl; */
419 | pReactor->res_ptr = mysql_store_result(pReactor->mysql);
420 | pReactor->sqlrow = mysql_fetch_row(pReactor->res_ptr);
421 | if(!pReactor->sqlrow)
422 | {
423 | strclientmsg += "You have to register first";
424 | //my_logger->error("select error {}", mysql_error(pReactor->mysql));
425 | }
426 | else
427 | {
428 | int ret;
429 | if(strcmp(pReactor->sqlrow[0], password) == 0)
430 | {
431 | pReactor->m_clientname.push_back(str);
432 | strclientmsg += "LOG IN SUCCESS";
433 | std::cout<res_ptr);
437 | memset(query, 0, sizeof(query));
438 | sprintf(query,"select clientfd from UserInfo where username='%s'",name);
439 | ret=pReactor->sqlQuery(query);
440 | if(ret == -1)
441 | {
442 | my_logger->error("select error {}", mysql_error(pReactor->mysql));
443 | }
444 | pReactor->res_ptr=mysql_store_result(pReactor->mysql);
445 | pReactor->sqlrow=mysql_fetch_row(pReactor->res_ptr);
446 | if(clientfd!=atoi(pReactor->sqlrow[0]))
447 | {
448 | memset(query, 0, sizeof(query));
449 | sprintf(query,"update UserInfo set clientfd=%d where username='%s'",clientfd,name);
450 | ret=pReactor->sqlQuery(query);
451 | if(ret == -1)
452 | {
453 | my_logger->error("update error {}", mysql_error(pReactor->mysql));
454 | }
455 | my_logger->info("server msg:{} have changed client to LOGIN",name);
456 | }
457 | memset(query,0,sizeof(query));
458 | sprintf(query,"update UserInfo set online=%d where username='%s'",1,name);
459 | pReactor->sqlQuery(query);
460 | }
461 | else
462 | {
463 | strclientmsg += "password is wrong";
464 | }
465 | //continue;
466 | if(mysql_errno(pReactor->mysql))
467 | {
468 | my_logger->error("Retrive error {}", mysql_error(pReactor->mysql));
469 | }
470 |
471 | }
472 | mysql_free_result(pReactor->res_ptr);
473 | }
474 | else if(buff[0]==FRIENDSLIST)
475 | {
476 | char query[100];
477 | char name[20];
478 | std::string rec(buff);
479 | strcpy(name,rec.substr(1,rec.size()-1).c_str());
480 | //std::cout<<"FRIENDLIST name:"<sqlQuery(query);
484 | if(ret==-1)
485 | {
486 | my_logger->error("select friends error:{}",mysql_error(pReactor->mysql));
487 | }
488 | pReactor->res_ptr=mysql_store_result(pReactor->mysql);
489 | int rows=(int)mysql_num_fields(pReactor->res_ptr);
490 | //std::cout<<"clientfd:"< friendsmsg;
492 | std::string friendsmsg;
493 | int count=0;
494 | std::string tempstr;
495 | while((pReactor->sqlrow=mysql_fetch_row(pReactor->res_ptr)))
496 | {
497 | int i;
498 | for(i=0;isqlrow[i];
501 | friendsmsg+=":";
502 | //std::cout<<"friendsmsg:"<res_ptr);
515 |
516 | }
517 | //ONLINESTATE
518 | else if(buff[0]==ONLINESTATE)
519 | {
520 | //pReactor->onlineState_fd=clientfd;
521 | char query[100];
522 | sprintf(query,"select username,online,pic from UserInfo");
523 | pReactor->sqlQuery(query);
524 | pReactor->res_ptr=mysql_store_result(pReactor->mysql);
525 | int count=0;
526 | std::string namemsg;
527 | std::string onlinemsg;
528 | std::string picmsg;
529 | std::string allmsg;
530 | std::string tempstr;
531 | while((pReactor->sqlrow=mysql_fetch_row(pReactor->res_ptr)))
532 | {
533 | namemsg+=pReactor->sqlrow[0];
534 | onlinemsg+=pReactor->sqlrow[1];
535 | picmsg+=pReactor->sqlrow[2];
536 | allmsg+=namemsg+","+onlinemsg+","+picmsg+",:";
537 | tempstr+=allmsg;
538 | //send(clientfd,allmsg.c_str(),allmsg.size(),0);
539 | namemsg.clear();
540 | onlinemsg.clear();
541 | picmsg.clear();
542 | allmsg.clear();
543 | count++;
544 | }
545 | char str[5];
546 | sprintf(str,"%d",count);
547 | tempstr+=str;
548 | //std::cout<<"ONLINESTATE tempstr--"<res_ptr);
551 | }
552 | else if(buff[0]==PICCHANGE)
553 | {
554 | std::string rec(buff);
555 | auto it=rec.find(':');
556 | char name[20];
557 | int pic,ret;
558 | char query[100];
559 | strcpy(name,rec.substr(1,it-1).c_str());
560 | std::cout<<"name "<sqlQuery(query);
565 | if(ret==-1)
566 | {
567 | my_logger->error("update pic error:{}",mysql_error(pReactor->mysql));
568 | }
569 | }
570 | //聊天信息
571 | else if(buff[0] == MESSAGE)
572 | {
573 | strclientmsg += buff;
574 | }
575 | // TODO:添加好友消息
576 | else if(buff[0] == ADDFRIEND)
577 | {
578 | std::string rec(buff);
579 | char query[100];
580 | char fromname[20],toname[20];
581 | auto it=rec.find('+');
582 | strcpy(fromname,rec.substr(1,it-1).c_str());
583 | strcpy(toname,rec.substr(it+1,rec.size()-1).c_str());
584 | sprintf(query,"select username from UserInfo where username='%s'",toname);
585 | pReactor->sqlQuery(query);
586 | pReactor->res_ptr = mysql_store_result(pReactor->mysql);
587 | pReactor->sqlrow = mysql_fetch_row(pReactor->res_ptr);
588 | mysql_free_result(pReactor->res_ptr);
589 | if(!pReactor->sqlrow)
590 | {
591 | strclientmsg+="The name is wrong";
592 | }
593 | else
594 | {
595 | memset(query,0,sizeof(query));
596 | sprintf(query,"select friends from %s where friends='%s'",fromname,toname);
597 | pReactor->sqlQuery(query);
598 | pReactor->res_ptr=mysql_store_result(pReactor->mysql);
599 | pReactor->sqlrow=mysql_fetch_row(pReactor->res_ptr);
600 | mysql_free_result(pReactor->res_ptr);
601 | if(pReactor->sqlrow)
602 | {
603 | strclientmsg+="you are have been friends!";
604 | }
605 | else
606 | {
607 | memset(query,0,sizeof(query));
608 | sprintf(query,"select clientfd from UserInfo where username='%s'",toname);
609 | pReactor->sqlQuery(query);
610 | pReactor->res_ptr=mysql_store_result(pReactor->mysql);
611 | pReactor->sqlrow=mysql_fetch_row(pReactor->res_ptr);
612 | int tg_clientfd=atoi(pReactor->sqlrow[0]);
613 | std::cout<<"tg_clientfd: "<sqlQuery(query1);
646 | ret=pReactor->sqlQuery(query2);
647 | pReactor->sqlQuery(query);
648 | pReactor->res_ptr=mysql_store_result(pReactor->mysql);
649 | pReactor->sqlrow=mysql_fetch_row(pReactor->res_ptr);
650 | int tg_clientfd=atoi(pReactor->sqlrow[0]);
651 | if(ret == -1)
652 | {
653 | my_logger->error("insert error {}", mysql_error(pReactor->mysql));
654 | }
655 | std::string str="*ACCEPT.";
656 | send(tg_clientfd,str.c_str(),str.size(),0);
657 | strclientmsg+=buff;
658 | }
659 | else if(buff[0]==REFUSE)
660 | {
661 | std::string rec(buff);
662 | char fromname[20];
663 | char query[100];
664 | int ret;
665 | strcpy(fromname,rec.substr(1,rec.size()-1).c_str());
666 | sprintf(query,"select clientfd from UserInfo where username='%s'",fromname);
667 | ret=pReactor->sqlQuery(query);
668 | if(ret==-1)
669 | {
670 | my_logger->error("select error {}",mysql_error(pReactor->mysql));
671 | }
672 | pReactor->res_ptr=mysql_store_result(pReactor->mysql);
673 | pReactor->sqlrow=mysql_fetch_row(pReactor->res_ptr);
674 | if(!pReactor->sqlrow)
675 | {
676 | my_logger->info("server msg:there is no user called {} in database UserInfo",fromname);
677 | }
678 | int tg_clientfd=atoi(pReactor->sqlrow[0]);
679 | std::string msg="your requet had been refused...";
680 | send(tg_clientfd,msg.c_str(),msg.size(),0);
681 | }
682 | else
683 | {
684 | strclientmsg+=buff;
685 | }
686 | }
687 | //std::cout<<"run3..."<info("client msg: {}", strclientmsg.substr(1,strclientmsg.size()-1));
696 | }
697 | else
698 | {
699 | if(strclientmsg!="")
700 | {
701 | my_logger->info("client msg: {}", strclientmsg);
702 | }
703 | }
704 |
705 | if(strclientmsg[0] == MESSAGE||strclientmsg[0] == ACCEPT)
706 | {
707 | strclientmsg.erase(0, 1); //将命令标识符去掉
708 | /* 将消息加上时间戳 */
709 | ostimestr << "[" << nowstr->tm_year + 1900 << "-"
710 | << std::setw(2) << std::setfill('0') << nowstr->tm_mon + 1 << "-"
711 | << std::setw(2) << std::setfill('0') << nowstr->tm_mday << " "
712 | << std::setw(2) << std::setfill('0') << nowstr->tm_hour << ":"
713 | << std::setw(2) << std::setfill('0') << nowstr->tm_min << ":"
714 | << std::setw(2) << std::setfill('0') << nowstr->tm_sec << " ] ";
715 |
716 | strclientmsg.insert(0, ostimestr.str());//将时间戳插入到消息字符串的前面
717 | }
718 | else//不是交流的消息(注册、登录信息),就直接单独发送给客户端,不用广播
719 | {
720 | if(strclientmsg!="")
721 | {
722 | send(clientfd, strclientmsg.c_str(), strclientmsg.length(), 0);
723 | }
724 | continue;//阶数本次循环,不会再广播
725 | }
726 |
727 | /* 将消息交给发送广播消息的线程 */
728 | pReactor->m_msgs.push_back(strclientmsg);
729 | pthread_cond_signal(&pReactor->m_send_cond);
730 | //std::cout<<"run4..."<pThis;
740 |
741 | while(!pReactor->m_bStop)
742 | {
743 | std::string strclientmsg;
744 |
745 | pthread_mutex_lock(&pReactor->m_send_mutex);
746 | /* 注意!要用while循环等待 */
747 | while(pReactor->m_msgs.empty())
748 | pthread_cond_wait(&pReactor->m_send_cond, &pReactor->m_send_mutex);//线程阻塞在条件变量上等待
749 |
750 | //线程被唤醒,取出列首数据,并将列首弹出
751 | strclientmsg = pReactor->m_msgs.front();
752 | pReactor->m_msgs.pop_front();
753 | pthread_mutex_unlock(&pReactor->m_send_mutex);
754 |
755 | std::cout << std::endl;
756 |
757 |
758 | while(1)
759 | {
760 | int nSend;
761 | int clientfd;
762 | //广播消息(向所有与服务器建立连接的客户端发送消息)
763 | for(auto it = pReactor->m_fds.begin(); it != pReactor->m_fds.end(); it++)
764 | {
765 | clientfd = *it;
766 | //std::cout<<"------onlineState_fd-----"<onlineState_fd<onlineState_fd)
768 | // continue;
769 | nSend = send(clientfd, strclientmsg.c_str(), strclientmsg.length(), 0);
770 | if(nSend == -1)
771 | {
772 | if(errno == EWOULDBLOCK)
773 | {
774 | sleep(10);
775 | continue;
776 | }
777 | else
778 | {
779 | my_logger->error("send error, fd = {}", clientfd);
780 | pReactor->close_client(clientfd);
781 | break;
782 | }
783 | }
784 | }
785 |
786 | my_logger->info("send: {}", strclientmsg);
787 | /* 发送完把缓冲区清干净 */
788 | strclientmsg.clear();
789 |
790 | //代表整个while循环只执行一次
791 | if(strclientmsg.empty())
792 | break;
793 | }
794 | }
795 |
796 | return NULL;
797 | }
798 |
799 | //数据库连接
800 | int MyReactor::connect()
801 | {
802 | mysql = mysql_init(NULL);//数据库初始化
803 | if(!mysql)
804 | {
805 | my_logger->error("mysql init falied");
806 | return -1;
807 | }
808 |
809 | /* root为用户名,mysql123为密码,ChatRoom为要连接的database */
810 | mysql = mysql_real_connect(mysql, IP, "root", "mysql123", "ChatRoom", 0, NULL, 0);//连接到数据库
811 |
812 | if(mysql)
813 | {
814 | my_logger->info("MySQL connection success");
815 | }
816 | else
817 | {
818 | my_logger->warn(" MySQL connection failed");
819 | }
820 | return 0;
821 | }
822 |
823 | //数据库操作
824 | int MyReactor::sqlQuery(const char* query)
825 | {
826 | int res = mysql_query(mysql, query);
827 | //std::cout<<"query res= "<
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include //for htonl() and htons()
11 | #include
12 | #include
13 | #include
14 | #include //for signal()
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include //for std::setw()/setfill()
25 | #include
26 |
27 | #include
28 |
29 | #include
30 | #include "spdlog/spdlog.h"
31 | #include "spdlog/sinks/stdout_color_sinks.h"
32 |
33 | #include "command.h"
34 |
35 | #include
36 |
37 | #define WORKER_THREAD_NUM 5
38 |
39 |
40 | class MyReactor{
41 | public:
42 | MyReactor();
43 | ~MyReactor();
44 |
45 | /* 初始化socket和线程,供应用程序调用 */
46 | bool init(const char *ip, short nport);
47 |
48 | bool uninit();
49 |
50 | bool close_client(int clientfd);//关闭客户端
51 |
52 | static void* main_loop(void* loop);
53 |
54 | //数据库操作
55 | int connect();
56 | int sqlQuery(const char*);
57 |
58 | private:
59 | /* 见条款6,阻止有人调用复制构造函数和赋值运算符构造函数 */
60 | MyReactor(const MyReactor& rhs);
61 | MyReactor& operator = (const MyReactor& rhs);
62 |
63 | static void *accept_thread_proc(void* args);//接收信息线程工作函数
64 | static void *worker_thread_proc(void* args);//
65 |
66 | static void *send_thread_proc(void* args);//发送信息线程工作函数
67 |
68 | bool create_server_listener(const char* ip, short port);
69 |
70 |
71 | private:
72 | /* 服务器端的socket */
73 | int m_listenfd = 0;
74 | /* 让线程可以修改它 */
75 | int m_epollfd = 0;
76 | /* 线程ID */
77 | pthread_t m_accept_threadid;//接收信息线程Pid
78 | pthread_t m_threadid[WORKER_THREAD_NUM];//工作线程pid[]
79 |
80 | pthread_t m_send_threadid;//发送广播的线程pid
81 |
82 | //静态初始化线程锁
83 | /* 接受客户的信号量 */
84 | pthread_mutex_t m_accept_mutex = PTHREAD_MUTEX_INITIALIZER;
85 | /* 有新连接的条件变量 */
86 | pthread_cond_t m_accept_cond = PTHREAD_COND_INITIALIZER;
87 | /* 添加、取出客户链表的信号量 */
88 | pthread_mutex_t m_client_mutex = PTHREAD_MUTEX_INITIALIZER;
89 | /* 通知工作线程有客户消息的条件变量 */
90 | pthread_cond_t m_client_cond = PTHREAD_COND_INITIALIZER;
91 |
92 | pthread_mutex_t m_send_mutex = PTHREAD_MUTEX_INITIALIZER;//发送信息的线程锁
93 | pthread_cond_t m_send_cond = PTHREAD_COND_INITIALIZER;
94 | std::deque m_msgs;
95 |
96 | pthread_mutex_t m_cli_mutex = PTHREAD_MUTEX_INITIALIZER;//添加accept后的文件描述符的互斥锁
97 | pthread_cond_t m_cli_cond = PTHREAD_COND_INITIALIZER;
98 |
99 | std::set m_fds;//存放accept后的文件描述符
100 |
101 | /* 存储连接客户的链表,用队列也一样*/
102 | std::list m_clientlist;
103 | pthread_mutex_t m_clie_name=PTHREAD_MUTEX_INITIALIZER;
104 | std::list m_clientname;
105 | int onlineState_fd=0;
106 |
107 | /* 决定主线程、accept线程、工作线程是否继续迭代 */
108 | bool m_bStop = false;//false代表迭代(一直进行下去)
109 |
110 | /* MySQL数据库 */
111 | MYSQL *mysql;
112 | MYSQL_RES *res_ptr;
113 | MYSQL_ROW sqlrow;
114 | };
115 |
116 | #endif
117 |
--------------------------------------------------------------------------------
/server_mysql/command.h:
--------------------------------------------------------------------------------
1 | #ifndef COMMAND_H
2 | #define COMMAND_H
3 |
4 | #define IP "122.51.90.199"
5 | #define REGISTER '1'
6 | #define LOGIN '2'
7 | #define MESSAGE '3'
8 | #define ADDFRIEND '4'
9 | #define ADDREQUEST '5'
10 | #define ACCEPT '6'
11 | #define REFUSE '7'
12 | #define FRIENDSLIST '8'
13 | #define ONLINE '9'
14 | #define ONLINESTATE 'o'
15 | #define PICCHANGE 'p'
16 | #endif // COMMAND_H
17 |
--------------------------------------------------------------------------------
/server_mysql/main:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CXHGT/TCP-ChatRoom/99790ff02ae5bb040e525390561b8d769ec9415b/server_mysql/main
--------------------------------------------------------------------------------
/server_mysql/main.cpp:
--------------------------------------------------------------------------------
1 | #include "MyReactor.h"
2 |
3 |
4 | #include "spdlog/sinks/daily_file_sink.h"
5 | #include "spdlog/sinks/basic_file_sink.h"
6 | auto main_logger = spdlog::stdout_color_mt("main_logger");
7 |
8 |
9 | MyReactor g_reactor;
10 |
11 |
12 | void prog_exit(int signo)
13 | {
14 | main_logger->info("program recv signal {} to exit.", signo);
15 | g_reactor.uninit();//关闭服务器
16 | }
17 |
18 | void daemon_run()
19 | {
20 | int pid;
21 | signal(SIGCHLD, SIG_IGN);
22 | pid = fork();
23 | if (pid < 0)
24 | {
25 | main_logger->error("fork error");
26 | exit(-1);
27 | }
28 | else if (pid > 0) {
29 | exit(0);
30 | }
31 | //之前parent和child运行在同一个session里,parent是会话(session)的领头进程,
32 | //parent进程作为会话的领头进程,如果exit结束执行的话,那么子进程会成为孤儿进程,并被init收养。
33 | //执行setsid()之后,child将重新获得一个新的会话(session)id。
34 | //这时parent退出之后,将不会影响到child了。
35 | setsid();
36 | int fd;
37 | fd = open("/dev/null", O_RDWR, 0);
38 | if (fd != -1)
39 | {
40 | dup2(fd, STDIN_FILENO);
41 | dup2(fd, STDOUT_FILENO);
42 | dup2(fd, STDERR_FILENO);
43 | }
44 | if (fd > 2)
45 | close(fd);
46 | }
47 |
48 |
49 | int main(int argc, char* argv[])
50 | {
51 | //设置信号处理
52 | signal(SIGCHLD, SIG_DFL);
53 | signal(SIGPIPE, SIG_IGN);
54 | signal(SIGINT, prog_exit);
55 | signal(SIGKILL, prog_exit);
56 | signal(SIGTERM, prog_exit);
57 |
58 | short port = 0;
59 | int ch;
60 | bool bdaemon = false;
61 | while ((ch = getopt(argc, argv, "p:d")) != -1)
62 | {
63 | switch (ch)
64 | {
65 | case 'd':
66 | bdaemon = true;
67 | break;
68 | case 'p':
69 | port = atol(optarg);
70 | break;
71 | }
72 | }
73 |
74 | if (bdaemon)
75 | daemon_run();
76 |
77 |
78 | if (port == 0)
79 | port = 12345;
80 |
81 | if (!g_reactor.init("0.0.0.0", 12345))
82 | return -1;
83 |
84 |
85 | g_reactor.main_loop(&g_reactor);
86 |
87 | main_logger->info("main exit");
88 |
89 | return 0;
90 | }
91 |
92 |
93 |
--------------------------------------------------------------------------------
/spdlog-1.x.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CXHGT/TCP-ChatRoom/99790ff02ae5bb040e525390561b8d769ec9415b/spdlog-1.x.zip
--------------------------------------------------------------------------------