diff options
| author | Andrew <saintruler@gmail.com> | 2021-04-26 23:16:32 +0400 |
|---|---|---|
| committer | Andrew <saintruler@gmail.com> | 2021-04-26 23:16:32 +0400 |
| commit | 82e4202ba125d4ebc1e7ab75e52938c0b7a97071 (patch) | |
| tree | 4a45a1b6bda945dd83740eed13aafa8fb4bef24e /server | |
| parent | 431ea111d2a5167b65a84620c16e28fd463f7985 (diff) | |
Added second listener to server and rewrote client in go.
Diffstat (limited to 'server')
| -rw-r--r-- | server/go.mod | 3 | ||||
| -rw-r--r-- | server/main.go | 167 | ||||
| -rw-r--r-- | server/utils.go | 70 |
3 files changed, 167 insertions, 73 deletions
diff --git a/server/go.mod b/server/go.mod new file mode 100644 index 0000000..1aa1135 --- /dev/null +++ b/server/go.mod @@ -0,0 +1,3 @@ +module vasthecat.ru/coursework-server + +go 1.16 diff --git a/server/main.go b/server/main.go index 7c67ead..e7f47fc 100644 --- a/server/main.go +++ b/server/main.go @@ -4,71 +4,9 @@ import ( "encoding/json" "log" "net" + "sync" ) -const ( - MESSAGE = "message" - AUTHENTICATE = "authenticate" - RENAME = "rename" -) - -const ( - SUCCESS = "success" - FAILURE = "failure" -) - -type Message struct { - Type string - Data string - User string -} - -type Response struct { - Status string - Data string -} - -func parseMessage(data []byte) Message { - var m Message - // TODO(andrew): Добавить обработку ошибок - json.Unmarshal(data, &m) - return m -} - -func toBytes(num uint32) []byte { - buf := make([]byte, 4) - var mask uint32 = 0x00FF - for i := 0; i < 4; i += 1 { - buf[4-i-1] = byte(num & mask) - num >>= 8 - } - return buf -} - -func fromBytes(data []byte) uint32 { - var num uint32 - for i := 0; i < 4; i += 1 { - num += uint32(data[i] << ((4 - i - 1) * 8)) - } - return num -} - -func sendMessage(conn net.Conn, message []byte) error { - size := uint32(len(message)) - - _, err := conn.Write(toBytes(size)) - if err != nil { - return err - } - - _, err = conn.Write(message) - if err != nil { - return err - } - - return nil -} - func handleConnection(conn net.Conn) { defer conn.Close() @@ -77,7 +15,7 @@ func handleConnection(conn net.Conn) { maxAuthAttempts := 5 authAttempts := 0 authenticated := false - buf := make([]byte, 256) + buf := make([]byte, 4096) for { if authAttempts >= maxAuthAttempts { @@ -108,12 +46,23 @@ func handleConnection(conn net.Conn) { rawMessage := buf[4 : size+4] message := parseMessage(rawMessage) - //fmt.Println(message.Data) if message.Type == AUTHENTICATE { // TODO(andrew): Добавить процесс аутентификации if true { authenticated = true + resp, _ := json.Marshal(Response{ + Status: SUCCESS, + Data: "Аутентификация прошла успешно", + }) + _ = sendMessage(conn, resp) + } else { + resp, _ := json.Marshal(Response{ + Status: FAILURE, + Data: "При аутентификации произошла ошибка", + }) + _ = sendMessage(conn, resp) } + continue } if !authenticated { @@ -146,19 +95,91 @@ func handleConnection(conn net.Conn) { } } +func reader(c chan Message) { + const maxMessages uint64 = 1024 + var count uint64 = 0 + for { + data := <-c + + received.Lock() + if count >= maxMessages { + received.data = []Message{data} + received.messageShift += maxMessages + } else { + received.data = append(received.data, data) + count += 1 + } + received.Unlock() + } +} + +func handleSender(conn net.Conn) { + received.Lock() + lastIndex := received.messageShift + received.Unlock() + + for { + var message Message + received.Lock() + idx := lastIndex - received.messageShift + if idx <= uint64(len(received.data)) { + message = received.data[idx] + } + received.Lock() + + resp, _ := json.Marshal(Response{ + Status: SUCCESS, + Data: message.serialize(), + }) + _ = sendMessage(conn, resp) + } +} + +var received struct { + sync.Mutex + data []Message + messageShift uint64 +} + func main() { + var wg sync.WaitGroup + + c := make(chan Message) + go reader(c) + sock, err := net.Listen("tcp", "localhost:8080") - defer sock.Close() handleError(err) + defer sock.Close() + wg.Add(1) + go func(sock net.Listener) { + for { + conn, err := sock.Accept() + if err == nil { + go handleConnection(conn) + } else { + break + } + } + wg.Done() + }(sock) - for { - conn, err := sock.Accept() - if err == nil { - go handleConnection(conn) - } else { - handleError(err) + senderSock, err := net.Listen("tcp", "localhost:8081") + handleError(err) + defer senderSock.Close() + wg.Add(1) + go func(sock net.Listener) { + for { + conn, err := sock.Accept() + if err == nil { + go handleSender(conn) + } else { + break + } } - } + wg.Done() + }(senderSock) + + wg.Wait() } func handleError(err error) { diff --git a/server/utils.go b/server/utils.go new file mode 100644 index 0000000..cd2069f --- /dev/null +++ b/server/utils.go @@ -0,0 +1,70 @@ +package main + +import ( + "encoding/json" + "net" +) + +const ( + MESSAGE = "message" + AUTHENTICATE = "authenticate" + RENAME = "rename" +) + +const ( + SUCCESS = "success" + FAILURE = "failure" +) + +type Message struct { + Type string + Data string + User string +} + +func (msg *Message) serialize() string { + data, _ := json.Marshal(msg) + return string(data) +} + +type Response struct { + Status string + Data string +} + +func toBytes(num uint32) []byte { + buf := make([]byte, 4) + var mask uint32 = 0x00FF + for i := 0; i < 4; i += 1 { + buf[4-i-1] = byte(num & mask) + num >>= 8 + } + return buf +} + +func fromBytes(data []byte) uint32 { + var num uint32 + for i := 0; i < 4; i += 1 { + num += uint32(data[i] << ((4 - i - 1) * 8)) + } + return num +} + +func sendMessage(conn net.Conn, message []byte) error { + size := uint32(len(message)) + + data := append(toBytes(size), message...) + _, err := conn.Write(data) + if err != nil { + return err + } + + return nil +} + +func parseMessage(data []byte) Message { + var m Message + // TODO(andrew): Добавить обработку ошибок + json.Unmarshal(data, &m) + return m +} |