【发布时间】:2016-03-24 07:36:04
【问题描述】:
假设我们对服务器有以下抽象(XMPP,但在这里并不重要):
type Server struct {
Addr string
Conn net.Conn
tlsCon *tls.Conn
R *bufio.Reader
SSL bool
reader chan string
}
还有一个辅助函数来初始化它:
func createServer(domain string) (s *Server, err error) {
conn, err := net.Dial("tcp", domain+":5222")
if err != nil {
return nil, err
}
s = &Server{domain, conn, nil, bufio.NewReader(conn), false, make(chan string, 8)}
go func(t *Server) {
for {
buf := bufsPool.Get().([]byte)
n, err := s.R.Read(buf)
if err == nil {
s.reader <- string(buf[:n])
} else {
fmt.Println(err)
}
}
}(s)
return s, err
}
这个想法很简单:创建一个连接,如果一切顺利,为它获取一个缓冲读取器(我不使用 conn.read 函数只是因为,如果服务器需要,我启动 TLS 连接并将 R 重新分配给reader 基于它创建的,但现在情况并非如此)。
现在我们有了两个函数,写和读:
func (s *Server) read() (t string) {
t = ""
Inn:
for {
select {
case u := <-s.reader:
fmt.Println("debug", u)
t += u
default:
break Inn
}
}
return t
}
所以我希望 read 函数接收 goroutine 发送的数据,该数据从 chan 的套接字(在 createServer() 中启动的那个)读取。这个想法是调用 write 而不是读取响应。我创建了所有这些,因为服务器有时将响应分为两部分,例如我必须做传统的 read() 2 次。 但这不起作用,我的读取函数(见上文)根本不返回任何内容。很可能,那是因为服务器无法发送回数据并且我的函数退出,因为 chan 中没有任何内容。但一个问题是,虽然我多次调用 write 和 read,但 read 总是什么都不返回。
所以我想我有一些一般的设计错误,问题是社区是否可以帮助我找到它。谢谢。
【问题讨论】:
-
有关如何从 Go 读取 XMPP 流的信息,请参阅 stackoverflow.com/questions/36105199/…。
-
哦,你问了这个问题。您需要使用 XML 解析器从 XMPP 流中正确解析节。您的问题意味着您依赖于数据流的缓冲和碎片。这通常不起作用。
标签: sockets go concurrency