summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorAndrew <saintruler@gmail.com>2021-04-26 23:16:32 +0400
committerAndrew <saintruler@gmail.com>2021-04-26 23:16:32 +0400
commit82e4202ba125d4ebc1e7ab75e52938c0b7a97071 (patch)
tree4a45a1b6bda945dd83740eed13aafa8fb4bef24e /server
parent431ea111d2a5167b65a84620c16e28fd463f7985 (diff)
Added second listener to server and rewrote client in go.
Diffstat (limited to 'server')
-rw-r--r--server/go.mod3
-rw-r--r--server/main.go167
-rw-r--r--server/utils.go70
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
+}