如果没有发送新行,如何读取服务器发送的数据(xml)

时间:2016-03-19 18:00:13

标签: sockets go buffered

假设我们尝试与发送回XML数据的服务器(XMPP)进行通信。我们可以使用

conn, err := net.Dial("tcp", s.Addr+":5222")
//...
r := bufio.NewReader(conn)
//...
s, err := s.R.ReadString(10) // to read a string

但是有一个问题是服务器没有发送\ 10(换行符号)符号。我也尝试了12但没有任何运气。 readLine函数也是如此,因为它也依赖于\ 10。那么如何读取服务器发送的数据? 我尝试使用'>'作为分隔符并成功接收部分消息(可预测)。我有一个想法循环,而错误是零,并使用'>'的分隔符但它也没有用。 我的研究表明,信息的最后一个符号实际上是'>' (62)并且最后没有任何其他内容。

1 个答案:

答案 0 :(得分:1)

使用xml.Decoder从XMPP流中读取节。

conn, err := net.Dial("tcp", s.Addr+":5222")
if err != nil {
    // handle error
}
dec := xml.NewDecoder(conn)

使用解码器Token方法读取根文档元素并跳过节之间的字符数据:

func readStartElement(dec *xml.Decoder) (xml.StartElement, error) {
    for {
        t, err := dec.Token()
        if err != nil {
            return xml.StartElement{}, err
        }
        switch t := t.(type) {
        case xml.StartElement:
            return t, nil
        }
    }
}

使用解码器DecodeElement方法阅读节:

func readStanza(dec *xml.Decoder) (interface{}, error) {
    se, err := readStartElement(dec)
    if err != nil {
        return nil, err
    }
    var v interface{}
    switch  se.Name.Space + " " + se.Name.Local {
    case "jabber:client message":
        v = &jabberMessage{} // jabberMessage is struct type defined by app for messages
    // Add other stanza types here.        
    default:
        v = &struct{}{}
    }
    if err := dec.DeocdeElement(v, &se); err != nil {
        return nil, err
    }
    return v, nil
}

Type switch关于readStanza返回值以处理不同类型的接收节。

客户端同步读取节。这是粗略的轮廓(忽略身份验证等)。

conn, err := net.Dial("tcp", s.Addr+":5222")
if err != nil {
    // handle error
}
dec := xml.NewDecoder(conn)

// read and discard root element
_, err := readStartElement(dec)
if err != nil {
     // handle error
}

// read stanzas
for {
   v, err := readStanza(dec)
   if err != nil {
       // handle error 
       // must break out of loop on error
   }
   switch v := v.(type) {
   case *jabberMessage:
        // handle message
   case *someOtherStanzaType:
        // handle other stanza types
        // ... and so on
   }
}