在开发源工具解决Oracle中的问题时,必须了解TNS协议。在努力理解TNS协议的时候,Oracle JDBC驱动程序(classes12.zip)会是一个很有用的资源
TNS头
每个TNS包都有一个8字节的包头。包最前面的两个字节用来表示包的长度–不包括包头的大小。和所有的值一样,大小是大端字节的方式存储的。如果进行了校验,那么校验和会被存放在下一个字(WORD)内–默认情况下会对校验和进行校验,该字(WORD)的值为0x0000。下面的一个字节用来表示包的类型–例如,最常见的类型如下所示:
Connect packet Type 1 Accept packet Type 2 Ack packet Type 3 Refuse Packet Type 4 Redirect Packet Type 5 Data Packet Type 6 NULL Packet Type 7 Abort Packet Type 9 Resend Packet Type 11 Marker Packet Type 12 Attention Packet Type 13 Control Packet Type 14
要连接Oracle的时候,在TNS级,客户机向服务器发送一个链接包(类型1),这个包会指定客户将要访问的服务器名称。假定Listener知道这样的服务,那么接下来有两种可能:Listener可能会发送一个接收包(类型2)或者它可能用一个重定向包(类型5)将客户机指定向到另一个端口。如果出现的是前一种情况,那么客户机将尝试进行身份验证。如果出现的是后一种情况,那么客户机会向自己被重定向的端口发送一个连接包并请求访问该服务。如果一切顺利的话,服务器会发出一个接收包并开始进行身份验证。所有的身份验证包都是类型为6的数据包。
如果Listener不知道客户机要求访问那个服务,那么它就会发送一个拒绝包–类型4。一旦通过身份验证,查询包和结果包都是数据包。偶尔您会看到类型为12(oxoC的包)–这是用来中断的标记包。例如,如果服务器希望客户机停止发送数据,那么它会向客户机发送一个标记包。
接下来继续介绍TNS包头的细节,下面的一个字节是包头标志位(header flag)。一般这些包头标志位是不使用的,不过在10g中客户机可能会将它的值设定为0x04。
最后的两个字节构成一个字(WORD),他用来存放头校验和–在默认情况下不使用这个字并将其设为0x000:
WORD 00 00 Pocket Size WORD 00 00 Packet Checksum Byte 00 Packet Type Byte 00 Flags Word 00 00 Header Checksum
在对包进行深入研究前,观察一下拒绝包(类型4)应该会有所帮助。拒绝包表示某种错误–例如,一个因“用户名/密码无效”而被拒绝登陆的错误–即ORA-01017。根绝这些错误,第54个字节指出了问题所在:A3代表无效的密码,a2表明没有这样的用户。很明显,即使从拒绝包中也可以得到可能有用的信息。
发现这篇文章被网友转载了:地址;而且因为163 blog的权重比这里高导致原帖变成了”转帖”,真是很令人头痛的事情,
转载请注明出处:www.oracledatabase12g.com 谢谢!