prelogin数据包的详细讲解可以见《SQL server jdbc之prelogin数据包》,本文主要讲解这个包的响应包,在jdbc中日志中可以得到这个响应包的内容如下所示:
04 01 00 1F 00 00 01 00 00 00 10 00 06 01 00 16 ................
00 01 05 00 17 00 00 FF 0D 00 06 41 00 00 00 ...........A...
针对响应包的内容解析是在文件SQLServerConnection.java文件的Prelogin函数中。首先函数通过tdsChannel累中的read函数读取响应包的内容。再针对这些内容进行解析。
第一个字节(0x04):表示的是包的类型
第二个字节(0x01):表示的是响应的状态(status),必须为01,否则报错
第三,四字节(0x00 0x1F):表示包的长度
第9个字节(0x00):这个字节如果为-1,则会显示“Prelogin response is missing version and/or encryption option.”的警告信息,并且终止解析后的内容(记为v1)。
第10,11个字节(0x00 0x10):这两个字节的十进制值+8必须要大于0(记为v2),这个是选项的偏移量.
第12,13两个字节(0x00 0x06):这个字节的十进制值必须要大于0(记为v3),这个是选项的长度
如果v2+v3大于了包的长度,则得到异常信息与警告信息。
包剩下的内容就是选项的内容了,需要根据v1的值来选择不同的处理方法,v1的取值为0或者1.其他的都为得到Ignoring prelogin response option的日志信息。
下面根据不同的v1的值来进行讲解,剩下的内容如下所示:
01 00 16 ................
00 01 05 00 17 00 00 FF 0D 00 06 41 00 00 00 ...........A...
1. 当v1的值为0
1)判断v3的值是否为6.如果不为6,则抛出异常,并且打印警告日志为:Version option length:" + v3 + " is incorrect. Correct value is 6。
2) 根据v2的值来取serverMajorVersion。从上面的数据包内容可以得到serverMajorVersion是0x0D(13)。
2. 当v1的值为1
1)判断v3的值是否为1,如果不为1,则抛出异常,并且打印警告日志为:Encryption option length:" + v3 + " is incorrect. Correct value is 1.
2)从v2的值作为数据包的下标来取得negotiatedEncryptionLevel的值。这个值必须是在0,1,2,3这四个数字之一。
如果客户端要求加密(连接串中设置了encrypt为true),则negotiatedEncryptionLevel的值必须为1或者3.
如果requestedEncryptionLevel是2,则negotiatedEncryptionLevel不能为3.
上面就是整个prelogin包的响应包的解析情况。