0

I try to create a sigle TCP connection client used for multiple write and read concurrently. For example the TCP Server will return value like you write. The problem is the data exchanged between write and read. I have tried with sync.Mutex but it still doesn't work.

My Result is :

2018/03/10 12:52:10 STRING 4:1 2018/03/10 12:52:10 STRING 5:6 2018/03/10 12:52:10 STRING 2:3 and so on 

My Expectation is :

2018/03/10 12:52:10 STRING 4:4 2018/03/10 12:52:10 STRING 5:5 2018/03/10 12:52:10 STRING 2:2 2018/03/10 12:52:10 STRING 3:3 

Here's my code : package main

import ( "bufio" "log" "net" "strconv" "sync" "time" ) type Cc struct { mux sync.Mutex rw *bufio.ReadWriter } func main() { addr := "127.0.0.1:3333" log.Println("Dial " + addr) conn, err := net.Dial("tcp", addr) cc := Cc{ rw: bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn)), } if err != nil { log.Println(err) } for i := 1; i <= 10; i++ { go testC(cc, strconv.Itoa(i)) } time.Sleep(60 * time.Second) } func testC(cc Cc, st string) { cc.mux.Lock() defer cc.mux.Unlock() _, err := cc.rw.WriteString(st + "\n") if err != nil { log.Println(err) // return errors.Wrap(err, "Could not send additional STRING data ("+strconv.Itoa(n)+" bytes written)") } // log.Println("Flush the buffer."s) err = cc.rw.Flush() if err != nil { log.Println(err) // return errors.Wrap(err, "Flush failed.") } time.Sleep(3 * time.Second) // Read the reply. // log.Println("Read the reply.") response, err := cc.rw.ReadString('\n') if err != nil { log.Println(err) // return errors.Wrap(err, "Client: Failed to read the reply: '"+response+"'") } log.Println("STRING " + st + ":" + response) // cc.mux.Unlock() } 

Sorry for my bad English, Thank You.

1
  • 3
    FYI, writing a unit test or just running go vet would show the problem immediately. Commented Mar 10, 2018 at 14:43

1 Answer 1

8

func testC(cc Cc, st string) actually takes a copy of cc. So, even with locking on a mutex, you actually locking on 10 copies of it which are totally independent. So, your locking code has no effect.

Try changing testC function signature to func testC(cc *Cc, st string). And then your call go testC(&cc, strconv.Itoa(i)).

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.