Mercurial
comparison gara/main.go @ 42:c2706ffb442b
[Gara] Peer to peer chat terminal app using go.
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Mon, 01 Dec 2025 21:00:10 -0800 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 41:d2bb317e01db | 42:c2706ffb442b |
|---|---|
| 1 package main | |
| 2 | |
| 3 import ( | |
| 4 "fmt" | |
| 5 "bytes" | |
| 6 "net" | |
| 7 ) | |
| 8 | |
| 9 type Client struct { | |
| 10 name string | |
| 11 conn net.Conn | |
| 12 message []byte | |
| 13 } | |
| 14 | |
| 15 var clients map[string]Client = make(map[string]Client) | |
| 16 var allowedCharacters = map[byte]bool{ | |
| 17 'a': true, 'b': true, 'c': true, 'd': true, 'e': true, | |
| 18 'f': true, 'g': true, 'h': true, 'i': true, 'j': true, | |
| 19 'k': true, 'l': true, 'm': true, 'n': true, 'o': true, | |
| 20 'p': true, 'q': true, 'r': true, 's': true, 't': true, | |
| 21 'u': true, 'v': true, 'w': true, 'x': true, 'y': true, 'z': true, | |
| 22 'A': true, 'B': true, 'C': true, 'D': true, 'E': true, | |
| 23 'F': true, 'G': true, 'H': true, 'I': true, 'J': true, | |
| 24 'K': true, 'L': true, 'M': true, 'N': true, 'O': true, | |
| 25 'P': true, 'Q': true, 'R': true, 'S': true, 'T': true, | |
| 26 'U': true, 'V': true, 'W': true, 'X': true, 'Y': true, 'Z': true, | |
| 27 } | |
| 28 | |
| 29 func IsChacterAllowed(chars []byte) bool { | |
| 30 for _, b := range chars { | |
| 31 if !allowedCharacters[b] { | |
| 32 return false | |
| 33 } | |
| 34 } | |
| 35 return true | |
| 36 } | |
| 37 | |
| 38 func ResetClient(client Client) { | |
| 39 ResetClientMessage(client) | |
| 40 delete(clients, client.conn.RemoteAddr().String()) | |
| 41 client.conn.Close() | |
| 42 } | |
| 43 | |
| 44 func ResetClientMessage(client Client) { | |
| 45 for i := range client.message { | |
| 46 client.message[i] = 0 | |
| 47 } | |
| 48 } | |
| 49 | |
| 50 func Loggers(value string) { | |
| 51 fmt.Println(value) | |
| 52 } | |
| 53 | |
| 54 func SendString(client Client, value string) { | |
| 55 fmt.Println("Notifying User: ", client.name) | |
| 56 client.conn.Write(([]byte)(value+"\n")) | |
| 57 } | |
| 58 | |
| 59 func SendToAll(currentClient Client) { | |
| 60 for key, client := range clients { | |
| 61 if currentClient.conn.RemoteAddr().String() == key { | |
| 62 continue | |
| 63 } | |
| 64 formattedMessage := fmt.Sprintf("%v: %v", currentClient.name, (string)(currentClient.message)) | |
| 65 SendString(client, formattedMessage) | |
| 66 } | |
| 67 } | |
| 68 | |
| 69 func HandleConnection(conn net.Conn) { | |
| 70 client := Client{name: "unknown", conn: conn, message: make([]byte, 100)} | |
| 71 defer ResetClient(client) | |
| 72 | |
| 73 SendString(client, "Hello good sir. What is your name?(less than 100 character and no special characters)\n") | |
| 74 for { | |
| 75 _, err := conn.Read(client.message) | |
| 76 if err != nil { | |
| 77 SendString(client, "Something went wrong. Try again.") | |
| 78 continue | |
| 79 } | |
| 80 | |
| 81 for i := 0; i < len(client.message) - 1; i++ { | |
| 82 if (string)(client.message[i:i+2]) == "\r\n" { | |
| 83 client.name = (string)(client.message[:i]) | |
| 84 break; | |
| 85 } | |
| 86 } | |
| 87 | |
| 88 if !IsChacterAllowed(([]byte)(client.name)) { | |
| 89 SendString(client, "Only allow alphabets.") | |
| 90 continue | |
| 91 } | |
| 92 if client.name[0] == (byte)('\r') { | |
| 93 continue | |
| 94 } | |
| 95 ResetClientMessage(client) | |
| 96 break | |
| 97 } | |
| 98 | |
| 99 clients[client.conn.RemoteAddr().String()] = client | |
| 100 | |
| 101 // Hnadle all messages. | |
| 102 for { | |
| 103 err_n := 0 | |
| 104 | |
| 105 if err_n > 10 { | |
| 106 break; | |
| 107 } | |
| 108 | |
| 109 _, err := conn.Read(client.message) | |
| 110 if err != nil { | |
| 111 Loggers("Something went wrong") | |
| 112 err_n += 1 | |
| 113 } | |
| 114 if bytes.Equal(([]byte)("close"), client.message[:5]) { | |
| 115 break | |
| 116 } else { | |
| 117 fmt.Println("Working....") | |
| 118 SendToAll(client) | |
| 119 } | |
| 120 } | |
| 121 } | |
| 122 | |
| 123 func main() { | |
| 124 PORT := ":4200"; | |
| 125 server_conn, err := net.Listen("tcp", PORT) | |
| 126 fmt.Println("Running on ", server_conn.Addr().String()) | |
| 127 | |
| 128 if err != nil { | |
| 129 Loggers("Couldn't run the server") | |
| 130 } | |
| 131 for { | |
| 132 conn, err := server_conn.Accept() | |
| 133 if err != nil { | |
| 134 Loggers("Couldn't accept a client") | |
| 135 } | |
| 136 go HandleConnection(conn) | |
| 137 } | |
| 138 } | |
| 139 |