在of开发的过程中或运行中,时常发生以下异常,查阅了官方资料和源码内容,发现这些异常都是由以下产生的:
下面的流级别的错误条件的定义如下:
特殊情况下:
--------------------------------------------------------------------------------
(1)<bad-format/> --------------------------------
实体发送XML,无法处理此错误可能是用来代替更具体的XML相关的错误
(2)<bad-namespace-prefix/>-----------------------
实体发送的命名空间前缀是不支持的,或已发送没有命名空间前缀的元素需要这样的前缀 。
(3)<conflict/>------------
服务器正在关闭这个实体的活动流,因为一个新的流已经开始与现有流的冲突。
(4)<connection-timeout/>-------------------------
实体与服务端连接超时
(5) <host-gone/>--------------------------
由初始实体在流头中提供的"to"属性值对应的主机名,域名不存在。
(6) <host-unknown>-----------------------------------
由初始实体在流头提供的"to"属性值不符合服务器的主机名。
(7)<improper-addressing/>--------------------
在两台服务器之间发送的节中,属性中没有赋值。
(8)<internal-server-error/>--------------------------
服务器配置错误或其他未定义的内部错误。
(9)<invalid-from/>---------------------------------------
提供一个"from"的地址jabber id 或与主机名不匹配的Jabber id或有效的授权域名服务器之间通过SASL或response,
或者在客户端和服务器通过身份验证和资源绑定协商。
(10)<invalid-id/> ---------------------------------
流ID或回拨ID是无效的或不符合以前提供的ID。
(11)<invalid-namespace/> --------------------------
流命名空间的名称是其他的东西比的“http://etherx.jabber.org/streams”或回拨命名空间名称是其他的东西比“闲聊:服务器:回拨”(见XML命名空间的名称前缀(XML命名空间前缀 ) )。
(12)<invalid-xml/> --------------------------------
实体无效的XML发送到服务器进行验证( 验证 (validation) )在流。
(13)<not-authorized/> -------------------
实体试图发送数据流已通过身份验证之前,或以其他方式没有被授权执行相关的操作流协商,接收实体必须处理问题的节之前发送流错误。
(14)<policy-violation/> - -------------------------------
实体违反了一些当地的服务政策;服务器可以选择在<text/>元素或应用程序特定的条件元素中指定策略。
(15)<resource-constraint/> -------------------------------
服务器缺乏必要的系统资源,服务的流。
(16)<restricted-xml/> -------------------------------------
实体试图发送限制的XML功能,如注释,处理指令,DTD,实体引用,或者未转义字符
(17)<see-other-host/> --------------------------------------
服务器将不提供服务给初始实体,但将流量重定向到另一台主机,服务器指定的备用主机名或IP地址(必须是一个有效的域标识符)的XML字符数据的<see-other-host/>元素。
(18)<system-shutdown/> -----------------------------------
服务器已被关闭,所有活动流被关闭。
(19)<undefined-condition/> -----------------------------------
错误的条件是在此列表中的其他条件所界定者之一,这个错误条件应该只用在应用程序特定条件的配合。
(20)<unsupported-stanza-type/> -------------------------------------
初始实体发送的第一级子流不支持的服务器。
(21)<unsupported-version/> -----------------------------------------
由初始实体在流头提供的'版本'属性值指定的一个版本是不支持的XMPP的服务器,服务器可以指定它支持的版本 <text/>元素。
(22)<xml-not-well-formed/> ------------------------------------------
初始实体发送,不能很好地形成所定义的XML [XML]
(23)<response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">dXNlcm5hbWU9IiIscmVhbG09InhtcHAubGI2Lm5ldCIsY25vbmNlPSIwNzY1YjU5NTc4YjI3YTY5MGUyNjI2NmNmMjBhMzliMTFmNTY0ZmY5MDc2MTQ0YTYyNmMwNGE0OGU3ZmFhYWEyIixuYz0wMDAwMDAwMSxxb3A9YXV0aCxkaWdlc3QtdXJpPSJ4bXBwL3htcHAubGI2Lm5ldCIscmVzcG9uc2U9NTdlODBmMzZmODlmMDI4NGVkNjgxNjc4ZjZiNWMyNjMsY2hhcnNldD11dGYtOCxub25jZT0icWJPZFVXT0lZTlYvNXV1T1hCc005WmhvWDJQWDNldk92RWZ0amhvRiI=</response>
由于客户端出发的消息符合法导致服务端解析错误而中断与客户端的连接,代码如下:
public void messageReceived(IoSession session, Object message) throws Exception {
// Get the stanza handler for this session
StanzaHandler handler = (StanzaHandler) session.getAttribute(HANDLER);
// Get the parser to use to process stanza. For optimization there is going
// to be a parser for each running thread. Each Filter will be executed
// by the Executor placed as the first Filter. So we can have a parser associated
// to each Thread
int hashCode = Thread.currentThread().hashCode();
XMPPPacketReader parser = parsers.get(hashCode);
if (parser == null) {
parser = new XMPPPacketReader();
parser.setXPPFactory(factory);
parsers.put(hashCode, parser);
}
// Update counter of read btyes
updateReadBytesCounter(session);
//System.out.println("RCVD: " + message);
// Let the stanza handler process the received stanza
try {
handler.process((String) message, parser);
} catch (Exception e) {
Log.error("Closing connection due to error while processing message: " + message, e);
Connection connection = (Connection) session.getAttribute(CONNECTION);
connection.close();
}
}
A、 正常的情况下详细流程如下:
1】客户端选择一个验证机制:
<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5'/>
2】: 服务器发送一个 [BASE64] 编码的挑战给客户端:
<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9ImF1dGgi
LGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNzCg==
</challenge>
解码后的挑战信息是:
realm="somerealm",nonce="OA6MG9tEQGm2hh",
qop="auth",charset=utf-8,algorithm=md5-sess
3】客户端发送一个[BASE64]编码的回应这个挑战:
<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
dXNlcm5hbWU9InNvbWVub2RlIixyZWFsbT0ic29tZXJlYWxtIixub25jZT0i
T0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5jPTAw
MDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5jb20i
LHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3LGNo
YXJzZXQ9dXRmLTgK
</response>
解码后的回应信息是:
username="somenode",realm="somerealm",
nonce="OA6MG9tEQGm2hh",cnonce="OA6MHXh6VqTrRk",
nc=00000001,qop=auth,digest-uri="xmpp/example.com",
response=d388dad90d4bbd760a152321f2143af7,charset=utf-8
4】: 客户端应答这个挑战:
<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
5】: 服务器通知客户端验证成功:
<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
B、非正常的情况
1】客户端选择一个验证机制:
<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5'/>
2】: 服务器发送一个 [BASE64] 编码的挑战给客户端:
<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9ImF1dGgi
LGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNzCg==
</challenge>
3】:客户端返回的数据:
<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>