arnaucube
arnaucube/goDDOSPublic Self-hosted repository
server sending messages to multiple clients works fine
arnaucode idoctnef@openmailbox.org
Thu, 16 Mar 2017 14:20:42 +0100
commit

c92299f831d4049381fa3abf88ef52b7b9f86c58

parent

aa94b72ec1b4193b01381eed2d49f5b98c018a12

2 files changed, 110 insertions(+), 30 deletions(-)

jump to
M client/main.go → client/main.go

@@ -5,12 +5,19 @@ "bufio"

"fmt" "net" "os" + "time" +) + +const ( + CONN_HOST = "localhost" + CONN_PORT = "3333" + CONN_TYPE = "tcp" ) func main() { //client https://systembash.com/a-simple-go-tcp-server-and-tcp-client/ // connect to this socket - conn, _ := net.Dial("tcp", "127.0.0.1:3333") + conn, _ := net.Dial(CONN_TYPE, CONN_HOST+":"+CONN_PORT) hostname, err := os.Hostname() if err != nil { fmt.Println(err)

@@ -20,7 +27,7 @@ fmt.Println("connecting to server as hostname:", hostname)

ip := getIp() fmt.Println("local ip:", ip) // send to socket - fmt.Fprintf(conn, hostname+", ip: "+ip.String()+"\n") + fmt.Fprintf(conn, "[client connecting] - [date]: "+time.Now().Local().Format(time.UnixDate)+" - [hostname]: "+hostname+", [ip]: "+ip.String()+"\n") for { message, err := bufio.NewReader(conn).ReadString('\n') if err != nil {
M server/main.go → server/main.go

@@ -5,6 +5,8 @@ "bufio"

"fmt" "net" "os" + "strconv" + "strings" ) const (

@@ -13,43 +15,114 @@ CONN_PORT = "3333"

CONN_TYPE = "tcp" ) -func main() { //server +var allClients map[*Client]int + +type Client struct { + outgoing chan string + reader *bufio.Reader + writer *bufio.Writer + conn net.Conn + connection *Client +} + +func (client *Client) Read() { + for { + line, err := client.reader.ReadString('\n') + if err == nil { + if client.connection != nil { + client.connection.outgoing <- line + } + fmt.Println("") + fmt.Println(line) + } else { + break + } + + } + + client.conn.Close() + delete(allClients, client) + if client.connection != nil { + client.connection.connection = nil + } + client = nil +} - fmt.Println("Launching server...") +func (client *Client) Write() { + for data := range client.outgoing { + client.writer.WriteString(data) + client.writer.Flush() + } +} +func (client *Client) Listen() { + go client.Read() + go client.Write() +} +func NewClient(connection net.Conn) *Client { + writer := bufio.NewWriter(connection) + reader := bufio.NewReader(connection) - // listen on all interfaces - ln, err := net.Listen(CONN_TYPE, CONN_HOST+":"+CONN_PORT) - if err != nil { - fmt.Println("Error listening:", err.Error()) - os.Exit(1) + client := &Client{ + // incoming: make(chan string), + outgoing: make(chan string), + conn: connection, + reader: reader, + writer: writer, + } + client.Listen() + + return client +} + +func watchConsoleInput(conn net.Conn) { + newcommand := bufio.NewReader(os.Stdin) + for { + text, _ := newcommand.ReadString('\n') + text = strings.TrimSpace(text) + // send newcommand back to client + if text != "" { + fmt.Println("console input command: " + text) + fmt.Println("sending command to " + strconv.Itoa(len(allClients)) + " connected clients") + for clientList, _ := range allClients { + //if clientList.connection == nil { + clientList.conn.Write([]byte(text + "\n")) + //} + } + fmt.Print("enter new command: ") + } } +} +func watchConnectionInput(client *Client) { + for clientList, _ := range allClients { + if clientList.connection == nil { + client.connection = clientList + clientList.connection = client + fmt.Println("Connected") + } - // Close the listener when the application closes. - defer ln.Close() - defer fmt.Println("ended") + } - fmt.Println("Listening on " + CONN_HOST + ":" + CONN_PORT) + allClients[client] = 1 + fmt.Println(strconv.Itoa(len(allClients)) + " connected clients") + fmt.Print("command to send to the clients: ") +} - // accept connection on port - c, err := ln.Accept() +func main() { + allClients = make(map[*Client]int) + listener, err := net.Listen(CONN_TYPE, CONN_HOST+":"+CONN_PORT) if err != nil { - fmt.Println("Error accepting: ", err.Error()) + fmt.Println("Error listening:", err.Error()) os.Exit(1) } - // will listen for message to process ending in newline (\n) - message, _ := bufio.NewReader(c).ReadString('\n') - // output message received - fmt.Print("client connected:", string(message), "\n") - for { - /*// will listen for message to process ending in newline (\n) - message, _ := bufio.NewReader(c).ReadString('\n') - // output message received - fmt.Print("client connected:", string(message), "\n")*/ + fmt.Println("Listening on " + CONN_HOST + ":" + CONN_PORT) - newcommand := bufio.NewReader(os.Stdin) - fmt.Print("command to send to the clients: ") - text, _ := newcommand.ReadString('\n') - // send new string back to client - c.Write([]byte(text + "\n")) + for { + conn, err := listener.Accept() + if err != nil { + fmt.Println(err.Error()) + } + client := NewClient(conn) + go watchConnectionInput(client) + go watchConsoleInput(client.conn) } }