详细问题是这样的: 我有两个一样的站点,分别为
site1 := "www.aaa.com:80"
site2 := "www.bbb.com:80"
一般创建一个连接是这样的:
conn, err := net.Dial("tcp", site1)
我想从站点获取数据,创建连接的时候,我想同时创建,但是谁先创建成功我就要谁。 就像我急着用某件物品,附近有两家超市,我安排两个人同时去买,买到了就行,而不用管是谁买到的。
func getBestConn()(net.Conn) {
ch := make(net.Conn, 1)
site1 := "www.aaa.com:80"
site2 := "www.bbb.com:80"
go func(){
cc, err := net.Dial("tcp", site1)
ch <- cc
}()
go func(){
cc, err := net.Dial("tcp", site2)
ch <- cc
}()
return <-cc
}
我写了上面的代码,但是它不能正常工作。 请问我该怎么做?
btw, 新年快乐
func getBestConn(addr1, addr2 string) (net.Conn, error) {
ch1 := make(chan net.Conn)
ch2 := make(chan net.Conn)
go func() {
cc, err := net.Dial("tcp", addr1)
if err != nil {
log.Logf("local connect: %s, %v", addr1, err)
}
ch1 <- cc
}()
go func() {
cc, err := net.Dial("tcp", addr2)
if err != nil {
log.Logf("local connect: %s, %v", addr2, err)
}
ch2 <- cc
}()
select {
case c := <-ch1:
// log.Logf("get ch1, %s - %s", c.LocalAddr(), c.RemoteAddr())
log.Logf("get ch1")
return c, nil
case c := <-ch2:
// log.Logf("get ch2, %s - %s", c.LocalAddr(), c.RemoteAddr())
log.Logf("get ch2")
return c, nil
case <-time.After(time.Second * 5):
log.Logf("timeout")
return nil, errors.New("timeout")
}
}
我似乎发现了一个问题,就是两个 conn 都可能成功,而返回之后我只能 close 一个。
这可如何是好。
1
mlkr 2018-01-01 02:19:49 +08:00 via Android 1
select ? https://gobyexample.com/select
|
2
snail1988 2018-01-01 10:42:37 +08:00 1
你的想法可以实现啊,不过你贴的代码有明显错误
``` func getBestConn()(net.Conn) { ch := make(chan net.Conn, 1) site1 := "www.baidu.com:80" site2 := "www.taobao.com:80" go func(){ cc, _ := net.Dial("tcp", site1) ch <- cc }() go func(){ cc, _ := net.Dial("tcp", site2) ch <- cc }() return <-ch } ``` |
4
suconghou 2018-01-01 13:48:01 +08:00 1
无缓冲 chan,入的时候用 select 和 default,后入的会阻塞,走 default close
|