-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.go
75 lines (63 loc) · 3.49 KB
/
server.go
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
package main
import (
"fmt"
"log"
"net"
"os"
"time"
)
func main() {
logFile, err := os.OpenFile("server_log.txt", os.O_WRONLY, os.FileMode(os.O_APPEND)) //открываем log файл
if err != nil {
panic(err)
}
defer logFile.Close() //отложенное закрытие
errorLog := log.New(logFile, "ERR: ", log.Ltime) //логгирование ошибок
ln, err := net.Listen("tcp", ":2020") //слушаем 2020 порт
if err != nil {
errorLog.Panic(err)
}
logFile.WriteString("INFO: server started " + time.Now().String() + "\n") //логгируем "сервер запущен"
count := 0 //счетчик подключеных клиентов
for {
conn, err := ln.Accept() //создали подключение
if err != nil {
errorLog.Panic(err)
}
logFile.WriteString("INFO: client connected " + time.Now().String() + "\n") //логгируем "подключился клиент"
go handleClient(conn, &count, logFile) //(горутина)работаем сразу с несколькими клиентами(передали объект conn, указатель на счетчик, указатель на лог файл)
}
}
func handleClient(conn net.Conn, count *int, logFile *os.File) {
defer conn.Close() //отложенное закрытие подключения
defer logFile.WriteString("INFO: client has been diconnected " + time.Now().String() + "\n\n") //логгируем "клиент отключен"
data := make([]byte, 100) //создаем дин.массив байт
for i := 0; i < len(data); i++ {
data[i] = 32 //инициализируем пробелами(32 в utf-8 = пробел)
}
conn.Read(data) //читаем из подключения данные
*count++ //прибавляем счетчик клиентов
//"укорачиваем" массив данных, избавляясь от лишних пробелов в конце массива
index := len(data) - 1
for data[index] == 32 {
data = data[:index]
index--
}
fmt.Printf("Client_%v: %v\n", *count, string(data)) //вывод в консоль номер клиента и того, что он нам отправил
logFile.WriteString("INFO: massage from client: " + string(data) + time.Now().String() + "\n") //логгируем месседж клиента
time.Sleep(3 * time.Second) //эмуляция работы
Reverse(&data) //переворачиваем строку
data = []byte(string(data) + ". Server written by Glazov Vadim M3O-109B-22\n") //добавляем необходимое
conn.Write(data) //отправляем данные клиенту
logFile.WriteString("INFO: massage to client: " + string(data) + time.Now().String() + "\n") //логгируем то, что отправили
time.Sleep(3 * time.Second) //эмуляция работы
}
// переворот строки
func Reverse(data *[]byte) {
runeData := []rune(string(*data))
k := len(runeData) / 2
for i := 0; i < k; i++ {
runeData[i], runeData[len(runeData)-1-i] = runeData[len(runeData)-i-1], runeData[i]
}
*data = []byte(string(runeData))
}