summaryrefslogtreecommitdiff
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
parent431ea111d2a5167b65a84620c16e28fd463f7985 (diff)
Added second listener to server and rewrote client in go.
-rw-r--r--client/main.go63
-rw-r--r--client/utils.go76
-rw-r--r--server/go.mod3
-rw-r--r--server/main.go167
-rw-r--r--server/utils.go70
-rw-r--r--tester.py7
6 files changed, 313 insertions, 73 deletions
diff --git a/client/main.go b/client/main.go
new file mode 100644
index 0000000..18796ae
--- /dev/null
+++ b/client/main.go
@@ -0,0 +1,63 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "log"
+ "net"
+ "sync"
+)
+
+func main() {
+ var wg sync.WaitGroup
+ conn, err := net.Dial("tcp", "localhost:8080")
+ handleError(err)
+ defer conn.Close()
+ wg.Add(1)
+ go func(conn net.Conn) {
+ buf := make([]byte, 4096)
+
+ authMsg, _ := json.Marshal(Message{
+ Type: AUTHENTICATE,
+ Data: "auth",
+ User: "andrew",
+ })
+ _ = sendMessage(conn, authMsg)
+
+ for i := 0; i < 20; i += 1 {
+ fmt.Printf("Sending %d request\n", i)
+ request, _ := json.Marshal(Message{
+ Type: MESSAGE,
+ Data: fmt.Sprintf("Hello, %d", i),
+ User: "andrew",
+ })
+ err = sendMessage(conn, request)
+ if err != nil {
+ break
+ }
+
+ fmt.Println("Waiting for response")
+ _, _ = conn.Read(buf)
+
+ size := fromBytes(buf[:4])
+ response := parseResponse(buf[4 : size+4])
+ fmt.Printf("Response: %s\n", response.Data)
+ }
+
+ exitMsg, _ := json.Marshal(Message{
+ Type: MESSAGE,
+ Data: "exit",
+ User: "andrew",
+ })
+ _ = sendMessage(conn, exitMsg)
+ wg.Done()
+ }(conn)
+
+ wg.Wait()
+}
+
+func handleError(err error) {
+ if err != nil {
+ log.Fatal(err)
+ }
+}
diff --git a/client/utils.go b/client/utils.go
new file mode 100644
index 0000000..c11bf17
--- /dev/null
+++ b/client/utils.go
@@ -0,0 +1,76 @@
+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
+}
+
+func parseResponse(data []byte) Response {
+ var r Response
+ json.Unmarshal(data, &r)
+ return r
+}
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
+}
diff --git a/tester.py b/tester.py
index 265d99b..26d694e 100644
--- a/tester.py
+++ b/tester.py
@@ -44,11 +44,18 @@ def main():
}
send_message(sock, json.dumps(request).encode())
+ response = sock.recv(4)
+ size = int_from_bytes(response)
+ response = sock.recv(size).decode()
+ print(f"Response: {response}")
+
for i in range(10000):
print(f"Sending {i} request")
+ # msg = input("Enter message: ")
request = {
"type": MESSAGE,
"data": f"hello, {i}",
+ # "data": msg,
"user": "andrew"
}
send_message(sock, json.dumps(request).encode())