如果不发送新行,如何读取由服务器发送的数据(xml) [英] How to read data (xml) sent by server if it doesn't send new line

查看:155
本文介绍了如果不发送新行,如何读取由服务器发送的数据(xml)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  conn,err:= net.Dial(tcp,s.Addr +:5222)
// ...
r:= bufio.NewReader(conn)
// ...
s,err:= sRReadString(10)//读取字符串

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

解决方案

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

  conn,err:= net.Dial(tcp,s.Addr +:5222)
if err!= nil {
//处理错误
}
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
}
}
}
code>

使用解码器

  func readStanza(dec * xml.Decoder)(interface {nofollow}> DecodeElement 方法来读取节:呃ror){
se,err:= readStartElement(dec)
if err!= nil {
return nil,err
}
var v interface {}
switch se.Name.Space ++ se.Name.Local {
casejabber:client message:
v =& jabberMessage {} // jabberMessage是由app定义的结构类型消息
//在这里添加其他节类型。
默认值:
v =& struct {} {}
}
if err:= dec.DeocdeElement(v,& se); err!= nil {
return nil,err
}
return v,nil
}

在readStanza的返回值上键入开关以处理不同类型的收到节。



客户端同步读取节。

  conn,err:= net.Dial(tcp,s.Addr + :5222)
if err!= nil {
//处理错误
}
dec:= xml.NewDecoder(conn)

/ /读取并放弃根元素
_,err:= readStartElement(dec)
if err!= nil {
//处理错误
}

//读取经节
用于{
v,err:= readStanza(dec)
if err!= nil {
//处理错误
// //必须跳出循环出错
}
switch v:= v。(类型){
case * jabberMessage:
//句柄消息
case * someOtherStanzaType:
//处理其他节类型
// ...等等
}
}


Let's say we try to communicate with a server (XMPP) which sends back XML data. We can use

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

But there is one problem that the server doesn't send the \10 (newline) symbol. I also tried 12 but without any luck. Same goes for readLine function as it also relies on \10. So how do I read the data sent by server? I tried using '>' as a delimiter and succeeded to receive only parts of the messages (predictable). I had an idea to loop while error is nil and use delimiter of '>' but it also didn't work. My research shown that the last symbol of the message is really '>' (62) and there is not any anything else at the end.

解决方案

Use an xml.Decoder to read stanzas from an XMPP stream.

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

Use the decoder Token method to read the root document element and to skip over character data between stanzas:

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
        }
    }
}

Use the decoder DecodeElement method to read a stanza:

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 on the return value from readStanza to handle the different types of received stanzas.

A client reads stanzas synchronously. Here's rough outline (ignoring authentication, etc).

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)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆