【发布时间】:2018-04-25 11:57:05
【问题描述】:
我有一个客户端正在向(从)服务器发送(接收)数据。客户端的代码类似:
conn, _ := net.Dial("tcp", "127.0.0.1:3456")
reader := bufio.NewReader(conn)
writer := bufio.NewWriter(conn)
for true {
writer.write(data)
reader.read()
}
现在,假设服务器经常崩溃导致conn 出现故障。这意味着for 循环中的write 和read 方法不会做任何事情,只会返回error。即使服务器在接下来的几秒钟内再次启动,客户端的for 循环代码也将无法与服务器通信,因为conn 出现故障。
我想要实现的是:让客户端在服务器再次恢复时继续运行。为此,我想到了以下方法:
func fixConnection(conn *net.Conn, reader **[]bufio.Reader, writer **[]bufio.Writer) net.Conn {
for true {
oneByte := make([] byte, 1, 1)
reader := bufio.NewReader(*conn)
_, err := reader.Read(oneByte)
if err != nil {
for true {
var tmpConn net.Conn
tmpConn, err = net.Dial("tcp", "127.0.0.1:3456")
if err == nil {
*conn = tmpConn
*reader = bufio.NewReader(*conn)
*writer = bufio.NewWriter(*conn)
}
time.Sleep(time.Millisecond * 100)
}
} else {
reader.UnreadByte()
time.Sleep(time.Millisecond * 500)
continue
}
}
}
然后我只在客户端添加一行:
conn, _ := net.Dial("tcp", "127.0.0.1:3456")
reader := bufio.NewReader(conn)
writer := bufio.NewWriter(conn)
// new line
go fixConnection(&conn, &reader, &writer)
for true {
writer.write(data)
reader.read()
}
我的方法至少存在一个问题:bufio 不是线程安全的,所以当fixConnection 改变读者(作者)时,可能会出现问题。在对读写器进行操作之前,有没有办法在不使用sync.Mutex 的情况下解决这个问题。
另外,有没有更好的方法来解决我上面提到的问题。即,当服务器再次恢复时再次连接到服务器?请注意,服务器可以随时接受多个客户端的连接。
【问题讨论】:
-
如果一端崩溃,TCP 连接将无法维持。您需要应用层重新连接功能。
-
是的,这就是我想要做的。服务器可以即时接受新的客户端。
-
到目前为止我知道,你不能轻易地读写。您必须写入并关闭连接以进行确认,然后重新打开连接并读取并等待对方关闭连接以进行确认。