如果服务器不发送新行,如何读取服务器发送的数据(xml)
How to read data (xml) sent by server if it doesn't send new line
假设我们尝试与发回 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。那么如何读取服务器发送的数据呢?
我尝试使用“>”作为分隔符并成功地只接收了部分消息(可预测)。我有一个想法在错误为 nil 时循环并使用 '>' 的分隔符,但它也没有用。
我的研究表明,消息的最后一个符号实际上是“>”(62),最后没有任何其他符号。
使用 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.DecodeElement(v, &se); err != nil {
return nil, err
}
return v, nil
}
Type switch 在 readStanza 的 return 值上处理不同类型的接收节。
客户端同步读取节。这是粗略的概述(忽略身份验证等)。
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
}
}
假设我们尝试与发回 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。那么如何读取服务器发送的数据呢? 我尝试使用“>”作为分隔符并成功地只接收了部分消息(可预测)。我有一个想法在错误为 nil 时循环并使用 '>' 的分隔符,但它也没有用。 我的研究表明,消息的最后一个符号实际上是“>”(62),最后没有任何其他符号。
使用 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.DecodeElement(v, &se); err != nil {
return nil, err
}
return v, nil
}
Type switch 在 readStanza 的 return 值上处理不同类型的接收节。
客户端同步读取节。这是粗略的概述(忽略身份验证等)。
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
}
}