Excel实战解析之项目进度图(excel做进度图)
579
2022-05-29
【golang】✔️实战✔️ 聊天室 ☢️建议手☢️
概述
服务端实现
客户端实现
日志
概述
今天我们会结合之前几节课的知识来综合实战一下, 实现一个聊天室.
服务端实现
运行的时候我们可以开启一个服务端和 N 个客户端, 来实现聊天室.
代码:
package main import ( "fmt" "log" "net" "os" "strings" "time" ) // ================常量================ const ( // 日志路径 log_path = "chat_room/" ) // ===============全局变量============== // 文件日志 var logFile *os.File // 日志类 var logger *log.Logger // 客户端连接, key: ip端口, value: 连接对象 var onlineConns = make(map[string]net.Conn) // 消息队列, 缓冲区 var message_quene = make(chan string, 1024) // 消息, 处理程序退出 var quitchan = make(chan bool) // 消息协程 func comsume_msg() { for { select { // 取出消息 case msg := <- message_quene: process_msg(msg) // 处理退出 case <- quitchan: break } } } // 消息解析协程 func process_msg(message string) { // 字符串切割 contents := strings.Split(message, "#") if len(contents) > 1 { // 取出地址 address := contents[0] // 取出消息 message := contents[1] // 删除首尾 address = strings.Trim(address, " ") // 在线连接 conn, ok := onlineConns[address] if ok { _, err := conn.Write([]byte(message)) fmt.Println("发送消息:", message, "目的地:", address) if err != nil { fmt.Println("在线连接发送失败") } } } else { // 查看list contents = strings.Split(message, "&") if contents[1] == "list" { var str = "" // 向每个客户端发送信息 for i := range onlineConns { // str += "||||" + i } // 在线连接 conn, ok := onlineConns[contents[0]] if ok { _, err := conn.Write([]byte(str)) if err != nil { fmt.Println("在线发送失败:", err) } } fmt.Println("发送消息:", str, "目的地:", conn.RemoteAddr()) logger.Println("发送消息:", str, "目的地:", conn.RemoteAddr()) } } } // 接收消息 func receive_info(conn net.Conn) { // 缓冲 buffer := make([]byte, 1024) // 循环读取 for { // 读取数据 nums, err := conn.Read(buffer) if err != nil { break } if nums != 0 { // 获取地址 address := conn.RemoteAddr() // 获取消息 message := string(buffer[:nums]) // 调试输出 fmt.Println("收到消息:", message, "来自:", address) logger.Println("收到消息:", message, "来自:", address) // 处理客户端退出 if message == "exit" { // 调试输出 fmt.Println("客户端:", conn.RemoteAddr(), "正在退出...") logger.Println("客户端:", conn.RemoteAddr(), "正在退出...") // 退出 client_exit(conn) } else{ // 消息队列存储消息 message_quene <- message } } } } // 处理退出 func client_exit(conn net.Conn) { // 获取地址 address := fmt.Sprint(conn.RemoteAddr()) // 客户端退出时, 从map中移除地址 delete(onlineConns, address) // 关闭连接 conn.Close() // 输出当前列表 fmt.Println("客户端列表:\n--------------------") logger.Println("客户端列表:\n--------------------") for i := range onlineConns { fmt.Println(i) } } // 错误处理 func error_check(err error) { if err != nil { fmt.Println("Error:", err) os.Exit(1) } } func main() { fmt.Println("服务端正在启动...") // 打开日志文件 name := fmt.Sprintf("%d_%02d_%02d_%02d_%02d_%02d_server.log", time.Now().Year(), time.Now().Month(), time.Now().Day(), time.Now().Hour(), time.Now().Minute(), time.Now().Second(), ) log_file, err := os.OpenFile((log_path + name), os.O_RDWR | os.O_CREATE, 0) if err != nil { fmt.Println("日志文件打开失败:", err.Error()) os.Exit(-1) } // 关闭 defer log_file.Close() // 创建一个日志对象 logger = log.New(log_file, "\r\n", log.Ldate | log.Ltime | log.Llongfile) logger.Println("写入日志, 服务器正在启动...") // 创建TCP服务端 listen_socket, err := net.Listen("tcp", "127.0.0.1:8888") error_check(err) // 关闭 defer listen_socket.Close() fmt.Println("服务端启动完毕, 等待连接...") // 协程 go comsume_msg() // 启动连接 for { // 连接新客户端 conn, err := listen_socket.Accept() error_check(err) fmt.Println("服务端连接到客服端, 客户端地址:", conn.RemoteAddr()) logger.Println("服务端连接到客服端, 客户端地址:", conn.RemoteAddr()) // 获取地址 address := fmt.Sprint(conn.RemoteAddr()) // 添加到全局变量 onlineConns[address] = conn // 遍历每一个连接 fmt.Println("客户端列表:\n--------------------") logger.Println("客户端列表:\n---------------------------------------------------") for i := range onlineConns { fmt.Println(i) logger.Println(i) } // 发送消息 go receive_info(conn) } }
1
2
3
4
5
6
7
8
9
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
客户端实现
package main import ( "bufio" "fmt" "net" "os" ) // 发送消息 func send_msg(conn net.Conn) { // 循环发送 for { // 读取键盘输入 reader := bufio.NewReader(os.Stdin) // 读取一行 data, _, _ := reader.ReadLine() // 发送输入的字符串 _, err := conn.Write(data) fmt.Println("发送消息:", string(data)) if err != nil { conn.Close() fmt.Println("Error:", err, "客户端关闭") os.Exit(0) } // 收到exit, 关闭客户端 if string(data) == "exit" { fmt.Println("客户端关闭") os.Exit(0) } } } func main() { fmt.Println("客服端正在建立连接...") // 建立网络连接 conn, err := net.Dial("tcp", "127.0.0.1:8888") if err != nil { fmt.Println("网络连接错误") os.Exit(1) } fmt.Println("客户端成功连接到服务端, 服务端地址:", conn.RemoteAddr()) // 发送消息 go send_msg(conn) // 接收消息 buffer := make([]byte, 1024) // 循环接收 for { // 读取消息 nums, err := conn.Read(buffer) if err != nil { fmt.Println("读取消息出错, 退出客户端") os.Exit(0) } fmt.Println("收到消息:", string(buffer[:nums])) } }
1
2
3
4
5
6
7
8
9
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
输出结果:
server:
服务端正在启动... 服务端启动完毕, 等待连接... 服务端连接到客服端, 客户端地址: 127.0.0.1:63776 客户端列表: -------------------- 127.0.0.1:63776 服务端连接到客服端, 客户端地址: 127.0.0.1:63777 客户端列表: -------------------- 127.0.0.1:63776 127.0.0.1:63777 收到消息: 127.0.0.1:63776&list 来自: 127.0.0.1:63776 发送消息: ||||127.0.0.1:63776||||127.0.0.1:63777 目的地: 127.0.0.1:63776 收到消息: 127.0.0.1:63777#hi, client2 来自: 127.0.0.1:63776 发送消息: hi, client2 目的地: 127.0.0.1:63777 收到消息: 127.0.0.1:63777&list 来自: 127.0.0.1:63777 发送消息: ||||127.0.0.1:63776||||127.0.0.1:63777 目的地: 127.0.0.1:63777 收到消息: 127.0.0.1:63776#hi, client1 来自: 127.0.0.1:63777 发送消息: hi, client1 目的地: 127.0.0.1:63776 收到消息: exit 来自: 127.0.0.1:63776 客户端: 127.0.0.1:63776 正在退出... 客户端列表: -------------------- 127.0.0.1:63777 收到消息: exit 来自: 127.0.0.1:63777 客户端: 127.0.0.1:63777 正在退出... 客户端列表: --------------------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
client1:
客服端正在建立连接... 客户端成功连接到服务端, 服务端地址: 127.0.0.1:8888 127.0.0.1:63776&list 发送消息: 127.0.0.1:63776&list 收到消息: ||||127.0.0.1:63776||||127.0.0.1:63777 127.0.0.1:63777#hi, client2 发送消息: 127.0.0.1:63777#hi, client2 收到消息: hi, client1 exit 发送消息: exit 客户端关闭
1
2
3
4
5
6
7
8
9
10
11
client2:
客服端正在建立连接... 客户端成功连接到服务端, 服务端地址: 127.0.0.1:8888 收到消息: hi, client2 127.0.0.1:63777&list 发送消息: 127.0.0.1:63777&list 收到消息: ||||127.0.0.1:63776||||127.0.0.1:63777 127.0.0.1:63776#hi, client1 发送消息: 127.0.0.1:63776#hi, client1 exit 发送消息: exit 客户端关闭
1
2
3
4
5
6
7
8
9
10
11
日志
2021/08/27 01:08:04 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:209: 写入日志, 服务器正在启动... 2021/08/27 01:08:07 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:231: 服务端连接到客服端, 客户端地址: 127.0.0.1:63776 2021/08/27 01:08:07 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:242: 客户端列表: --------------------------------------------------- 2021/08/27 01:08:07 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:245: 127.0.0.1:63776 2021/08/27 01:08:09 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:231: 服务端连接到客服端, 客户端地址: 127.0.0.1:63777 2021/08/27 01:08:09 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:242: 客户端列表: --------------------------------------------------- 2021/08/27 01:08:09 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:245: 127.0.0.1:63776 2021/08/27 01:08:09 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:245: 127.0.0.1:63777 2021/08/27 01:08:20 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:135: 收到消息: 127.0.0.1:63776&list 来自: 127.0.0.1:63776 2021/08/27 01:08:20 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:104: 发送消息: ||||127.0.0.1:63776||||127.0.0.1:63777 目的地: 127.0.0.1:63776 2021/08/27 01:08:31 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:135: 收到消息: 127.0.0.1:63777#hi, client2 来自: 127.0.0.1:63776 2021/08/27 01:08:42 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:135: 收到消息: 127.0.0.1:63777&list 来自: 127.0.0.1:63777 2021/08/27 01:08:42 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:104: 发送消息: ||||127.0.0.1:63776||||127.0.0.1:63777 目的地: 127.0.0.1:63777 2021/08/27 01:08:53 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:135: 收到消息: 127.0.0.1:63776#hi, client1 来自: 127.0.0.1:63777 2021/08/27 01:09:04 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:135: 收到消息: exit 来自: 127.0.0.1:63776 2021/08/27 01:09:04 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:142: 客户端: 127.0.0.1:63776 正在退出... 2021/08/27 01:09:04 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:168: 客户端列表: -------------------- 2021/08/27 01:09:11 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:135: 收到消息: exit 来自: 127.0.0.1:63777 2021/08/27 01:09:11 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:142: 客户端: 127.0.0.1:63777 正在退出... 2021/08/27 01:09:11 C:/Users/Windows/Desktop/project2/chat_room/server2/server.go:168: 客户端列表: --------------------
1
2
3
4
5
6
7
8
9
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
客服
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。