1
0
mirror of https://github.com/MADTeacher/go_basics.git synced 2025-11-29 05:36:55 +02:00

Глава 8

Допричесать игру
This commit is contained in:
Stanislav Chernyshev
2025-06-22 21:04:23 +03:00
parent b895709c86
commit d4e7211d1d
41 changed files with 1724 additions and 143 deletions

View File

@@ -0,0 +1,77 @@
package client
import (
"bufio"
"fmt"
"io"
"log"
"net"
"os"
"strings"
"sync"
)
var waitingGr sync.WaitGroup
func checkErr(err error) {
if err != nil {
log.Fatal(err)
}
}
func sendMessage(connection net.Conn, waitingGr *sync.WaitGroup) {
defer waitingGr.Done()
for {
reader := bufio.NewReader(os.Stdin) // считываем введенное сообщение
text, _ := reader.ReadString('\n')
if strings.TrimSuffix(strings.TrimSpace(text), "\r\n") == "/stop" {
// завершение работы клиента
break
} else {
_, err := connection.Write([]byte(text))
checkErr(err)
}
}
}
func receiveMessage(connection net.Conn, waitingGr *sync.WaitGroup) {
defer waitingGr.Done()
for {
// ждем сообщение от сервера и считываем его
message, err := bufio.NewReader(connection).ReadString('\n')
if err == io.EOF {
fmt.Println("Connection close!")
break
} else if err != nil {
fmt.Println(err.Error())
break
}
message = message[:len(message)-1] // обрезаем символ перевода на следующую строку
fmt.Println(string(message))
}
}
func RunClient(port int) {
// запускает реализацию клиента TCP и соединяет вас с нужным TCP-сервером
connection, err := net.Dial("tcp", fmt.Sprintf("localhost:%d", port))
checkErr(err)
fmt.Printf("The TCP server is %s\n", connection.RemoteAddr().String())
defer connection.Close()
waitingGr.Add(1)
fmt.Println("Enter name: ")
temp := bufio.NewReader(os.Stdin)
userName, _ := temp.ReadString('\n')
_, err = connection.Write([]byte(userName))
checkErr(err)
go sendMessage(connection, &waitingGr)
go receiveMessage(connection, &waitingGr)
waitingGr.Wait()
}

View File

@@ -0,0 +1,3 @@
module tcp/server
go 1.24

View File

@@ -0,0 +1,38 @@
package main
import (
"fmt"
"log"
"os"
"strconv"
"tcp/server/client"
"tcp/server/server"
)
const PORT = 8081
func checkErr(err error) {
if err != nil {
log.Fatal(err)
}
}
func main() {
if len(os.Args) != 2 {
fmt.Println("You didn't select a launch option!!!")
return
}
numGR, err := strconv.Atoi(os.Args[1])
checkErr(err)
switch numGR {
case 1:
fmt.Println("Server is running")
server.RunServer(PORT)
case 2:
fmt.Println("Client is running")
client.RunClient(PORT)
default:
log.Fatal("What pokemon is this?")
}
}

View File

@@ -0,0 +1,85 @@
package server
import (
"bufio"
"fmt"
"log"
"net"
)
var connections []net.Conn
func checkErr(err error) {
if err != nil {
log.Print(err)
}
}
func handleConnection(connection net.Conn) {
connections = append(connections, connection)
userName, _ := bufio.NewReader(connection).ReadString('\n')
userName = userName[:len(userName)-2]
_, err := connection.Write([]byte("Hi " + userName + "\n"))
checkErr(err)
for {
text, err := bufio.NewReader(connection).ReadString('\n')
if err != nil {
connection.Close()
removeConnection(connection)
broadCastMessage(userName+" is offline\n", connection)
break
}
broadCastMessage(userName+":"+text, connection)
}
}
func removeConnection(connection net.Conn) {
var i int
for i = range connections {
if connections[i] == connection {
break
}
}
if len(connections) > 1 {
connections = append(connections[:i], connections[i+1:]...)
} else {
connections = nil
}
}
func broadCastMessage(msg string, connection net.Conn) {
// отправка сообщения всем клиентам
for _, c := range connections {
if connection != c {
_, err := c.Write([]byte(msg))
checkErr(err)
}
}
msg = msg[:len(msg)-1]
fmt.Println(msg)
}
func RunServer(port int) {
// net.Listen возвращает Listener переменную,
// которая является общим сетевым прослушивателем для потоковых протоколов
listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
checkErr(err)
defer listener.Close()
for {
connection, err := listener.Accept() // ожидание подключения клиента к серверу
// Только после успешного вызова Accept()TCP-сервер может начать
// взаимодействовать с TCP-клиентами
if err != nil {
log.Print(err)
return
}
go handleConnection(connection)
}
}