How to fill a map with requests from client without erasing the current values


(snk) #1

I am a beginner in Golang, This is a TCP server that receives requests and sends back a hello message to the client attached with the client’s message(name) how can I fill those requests into a map without erasing the previous request. this is the code, the request is appended to the map but when the next comes, it replaces the current on.

// Goroutine and Socket programming TCP server
    //**************************************************
    //                 TCP 
    //----------------------------------------------------------

    package main

    import (
    	"bufio"
    	"fmt"
    	"net"
    	"time"
    )
    // check if there is any error and send a message. but it's better to remove panic later (it's not recommended to use it)
//***********************************************************************************************************************
func check(err error, message string) { 
	if err != nil {
		panic(err)
	}
	fmt.Printf("%s\n", message)
}
// Create the client structure that contains the client's name and the connection
//****************************************************************************

type ClientJob struct { 
	name string
	conn net.Conn
	
}

// Create the function,the channel with type struct
//*********************************************************

func generateResponses(clientJobs chan ClientJob) {
	for {
		// Wait for the next job to come off the queue.
		clientJob := <-clientJobs

		// Do something thats keeps the CPU buys for a whole second.
		for start := time.Now(); time.Now().Sub(start) < time.Second; {
		}

		// Send back the response.

		clientJob.conn.Write([]byte("Hello, " + clientJob.name))

		//clientJob:=make(chan ClientJob)
		//name:=make(chan string)
		//name:=<-clientJobs

		all := make(map[string]string) // create the map 
		all["client request"] =  clientJob.name// append the client requests on map
		fmt.Println("All requests in the slice", all) // show all the requests in the map

		
		
	}
		
}

// The main function
//***********************************

func main() {
	clientJobs := make(chan ClientJob) // declare the channel used in the function above
	go generateResponses(clientJobs)  // put the function in a goroutine
	
	ln, err := net.Listen("tcp", ":8080") // connect to the port 8080, it can be changed to any port if needed
	check(err, "Server is ready.") // show the message that the server is ready to receive
	//fmt.Println(<-clientJobs)
	// start checking the connection et receiving from the client and pass it into a goroutine and send it via a channel ClientJobs<-ClientJob{name, conn}
	for {
		conn, err := ln.Accept()
		check(err, "Accepted connection.")

		go func() {
			buf := bufio.NewReader(conn)

			for {
				name, err := buf.ReadString('\n')

				if err != nil {
					fmt.Printf("Client disconnected.\n")
					break
				}

				clientJobs <- ClientJob{name, conn} // pass the name and conn to the clientJobs channel
				
			}
				
	
		}()
	}
}

(Taalhach) #2

maps in golang are like hash tables in other languages. keys in map are UNIQUE which means that one key will be appearing in map only once for example

x := make(map[string]int)
x[client_request] = 1
x[client_request] = 2

no matter how many times key client_request appears in map its only last value will be staying in map.
Same thing is happening in your code what you are doing is every client’s request is inserted in map with key client request and for all requests this key is same
what you need to do is for every client request you need to have Different keys.
just append random number with or append timestamp after that you will be able to see all requests in map. replace last lines of func generateResponses with following lines

               all := make(map[string]string) // create the map
		key:= "client request"+ strconv.FormatInt(time.Now().Unix(),10)
		all[key] =  clientJob.name// append the client requests on map
		fmt.Println("All requests in the slice", all) // show all the requests in the map

time.Now().Unix() gives timestamp int64 and strconv.FormatInt(ts,10) changes timestamp into string

for further knowledge on maps look into this maps in golang and follow these learn_go_with_tests tutorials for better learning