0

I was trying to create a client server model to learn some stuff and I just tried sending(writing) data from client to server in a loop and it just don't worked well. I think that there are some concurrency issues and the client writes faster to server and the server than read multiple statements in one go. How can I maintain this concurrency so that only one statement written by the client at a time is read by the server. Here is the code to illustrate the problem in a better.

Here is the server handleConnection Function

func main() {

    conn, err := net.Listen("tcp", ":8080")
    if err != nil {
        log.Println("Error:", err)
    }

    for {
        ln, err := conn.Accept()
        if err != nil {
            log.Println("Error:", err)
            continue
        }

        go handleConnection(ln)
    }

}

func handleConnection(conn net.Conn) {
    buffer := make([]byte, 4096)

    for i := 0; i < 10; i++ {
        n, err := conn.Read(buffer)
        if err != nil {
            fmt.Println(err, i)
        }

        fmt.Printf("%s\n", buffer[:n])
    }

    fmt.Println("Done")

    conn.Close()
}

Here is the client writing data to server in loop.

func main() {
    conn, err := net.Dial("tcp", ":8080")
    if err != nil {
        log.Println("Error:", err)
        os.Exit(1)
    }

    for i := 0; i < 10; i++ {
        _, err = conn.Write([]byte("Rehan"))
        if err != nil {
            fmt.Println(err, i)
        }
    }

    fmt.Println("Done")
    conn.Close()
}

This is the output by the server. ![This is the Server output]1

Malt
  • 28,965
  • 9
  • 65
  • 105

1 Answers1

2

It isn't a concurrency issue. It's a networking issue.

TCP is a stream protocol, as such, a single read() from a socket doesn't correspond to a single write() from the other side.

Instead, reads return whatever is in the TCP buffer at the time of read, regardless whether it was sent by a single call to write() or a hundred.

If you want to read the data from the socket as separate messages, you need a way of separating them by using a delimiter, counting bytes, or some other method.

Malt
  • 28,965
  • 9
  • 65
  • 105
  • Thankyou Malt. It was quite helpful. – Muhammad Rehan Javed Oct 29 '19 at 11:37
  • Usually you use fix size message and padding when ever the message is short. Then on the server you read the right length. In your case `buffer := make([]byte, 5)` will get you the result you expect. – ZAky Oct 29 '19 at 12:05