在golang中如何在单个TCP连接上并发写入和读取?
我尝试创建一个用于并发多个写和读的单TCP连接客户端。例如,TCP服务器将像您编写的那样返回值。 问题在于写入和读取之间的数据交换。我试过使用sync.Mutex,但仍然不起作用 我的结果是:在golang中如何在单个TCP连接上并发写入和读取?,go,mutex,tcpclient,Go,Mutex,Tcpclient,我尝试创建一个用于并发多个写和读的单TCP连接客户端。例如,TCP服务器将像您编写的那样返回值。 问题在于写入和读取之间的数据交换。我试过使用sync.Mutex,但仍然不起作用 我的结果是: 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 我的期望是: 2018/03/10 12:52:10 STRING 4:4 2018/03/10
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
我的期望是:
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
这是我的密码:
包干管
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()
}
导入(
“布菲奥”
“日志”
“净额”
“strconv”
“同步”
“时间”
)
类型Cc结构{
多路复用器同步。互斥
rw*bufio.ReadWriter
}
func main(){
地址:=“127.0.0.1:3333”
log.Println(“拨号”+addr)
连接,错误:=网络拨号(“tcp”,地址)
cc:=cc{
rw:bufio.NewReadWriter(bufio.NewReader(康涅狄格州),bufio.NewWriter(康涅狄格州)),
}
如果错误!=零{
log.Println(错误)
}
对于i:=1;ifunc testC(cc-cc,st-string)实际上获取了cc的一个副本。因此,即使锁定了互斥锁,实际上也锁定了它的10个完全独立的副本。因此,锁定代码没有任何效果
尝试将testC函数签名更改为func-testC(cc*cc,st-string)
。然后调用go-testC(&cc,strconv.Itoa(i))
FYI,编写单元测试或只是运行go-vet
会立即显示问题。