首页 » 技术分享 » tds协议详细解析

tds协议详细解析

 

表格数据流(Tabular Data Stream, TDS)协议是一种数据库服务器和客户端间交互的应用层协议,
为微软SQL Server数据库和Sybase公司数据库产品所采用。

TDS 版本及SQLServer版本对应关系
4.2 Sybase SQL Server < 10 and Microsoft SQL Server 6.5
5.0 Sybase SQL Server >= 10
7.0 Microsoft SQL Server 7.0
7.1 Microsoft SQL Server 2000
7.2 Microsoft SQL Server 2005
7.3A,7.3B Microsoft SQL Server 2008

TDS消息类型
分为客户端消息和服务端消息
客户端消息:
预登陆请求(Pre-login):与服务器协商包括使用版本、加密与否等环境设置。
登录(Login):发送包括用户名,密码在内的用户信息,请求与服务器建立连接。
SQL命令(SQL Command):发送SQL命令或者批处理命令。
数据批量操作(Bulk Operation):带有批量数据的SQL操作请求。
远程过程调用(RPC):远程存储过程调用。
提醒(Attention):中断或取消当前操作。

服务器端消息:
预登陆响应(Pre-login Response)
登录响应(Login Response):返回包括名称、TDS版本号等在内的服务器消息。
数据(Raw Data):如果客户端请求返回结果为数据,前一响应数据包必须包含有列名称、数据类型等。
返回状态(Return Status):RPC调用返回状态。
返回参数(Return Parameters): RPC调用返回参数。
其他:包括响应完成、错误及信息、提醒确认等在内的其他消息。

TDS消息报文格式

TDS包头(8字节) + TDS数据(不定长)

TDS包头结构格式
Type + Status + Length + SPID + PacketID + WINDOW

Type: (1字节,unsigned char)标识当前TDS数据包的类型。

值 描述 数据
1 sql命令或批处理 有
2 登陆(TDS4.2) 有
3 RPC 有
4 服务端对客户端的数据响应 有
5 Unused 无
6 提醒信号 有
7 批量数据操作 有
8-13 Unused. 无
14 事务管理请求 有
15-16 Unused 无
17 SSPI消息 有
18 预登陆 有

Status:(1字节,unsigned char)标识当前的消息状态

值 描述
0x00 正常消息
0x01 表示此包为当前TDS会话中的最后一个TDS包
其他值忽略

Length (2字节,unsigned short int,网络字节序)包的长度包括包头

SPID (2字节,unsigned short int,网络字节序)服务端进程ID

PacketID (1字节,unsigned char)数据包计数

Window (1字节,unsigned char)当前未使用忽略

TDS数据
1、Pre-login
数据包格式
TDS包头(8字节)+ 字段指示头 + 负载数据

字段指示头格式为
Token(1字节)类型+ offset(2字节)偏移量+ length(2字节)长度
Token表示的信息根据offset(不包括8字节包头)和length在负载数据之中查找。

Token Value Description
Version和Subbuild 0x00 发送方的版本信息(四个字节)和Subbuild(两个字节)网络字节序
Encryption 0x01 加密相关
Instopt 0x02
THREADID 0x03 客户端进程ID
Mars 0x04 发送者要求MARS支持
Traceid 0x05 客户端应用程序跟踪id
Fedauthrequired 0x06 在使用集成身份验证标识时,发送方的认证库要求
Nonceopt 0x07 使用会话秘钥进行加密
Terminator 0xFF 字段指示结束,后面的数据是信息

2、Pre-Login Response
根据包头中Type为0x04判断为服务端回复报文,预登录响应消息是一个无标记的数据包数据流,其他与Pre-login格式一样

3、Login7
数据包格式
TDS包头(8字节)+ 登录报头(36字节)+ 字段指示头 + 信息

登录报头格式
Length(四字节):TDS登录报总长度不包括8字节的TDS报头。
TDSVersion (四字节):客户端指示服务端要使用的TDS版本号(如果客户机发送的TDSVersion值大于服务器识别的值,则服务器必须使用可以使用的最高TDS版本。如果客户机发送的TDSVersion值低于服务器识别的最高TDS版本,则服务器必须使用客户机发送的TDS版本)
PacketSie(四字节):包数量,判断还有没有后继包
ClientProgVer(四字节):接口库的版本
ClientPID(四字节):客户端进程ID号
ConnectionID(四字节):主服务器的连接ID
OptionFlags1(一字节):选项标志1
OptionFlags2(一字节):选项标志2
TypeFlags(一字节):类型标志(包括客户端发给服务端的SQL类型等)
OptionFlags3(一字节):选项标志3
ClientTimeZone(四字节):客户端的时区
ClientLCID(四字节):客户机排序的语言代码标识符(LCID)值

字段指示头格式:
字段 长度 描述
HostName offset(2字节)+ length(2字节) 客户端主机名称
UserName offset(2字节)+ length(2字节) 用户名
Password offset(2字节)+ length(2字节) 密码
AppName offset(2字节)+ length(2字节) 客户端应用程序名称
ServerName offset(2字节)+ length(2字节) 服务端主机名称
Unused offset(2字节)+ length(2字节) 预留
Extension offset(2字节)+ length(2字节) ; (introduced in TDS 7.4) 扩展
CltIntName offset(2字节)+ length(2字节) 接口库名称
Language offset(2字节)+ length(2字节) 语言
Database offset(2字节)+ length(2字节) 数据库名称
ClientID = 6BYTE
SSPI offset(2字节)+ length(2字节) sspi数据
AtchDBFile offset(2字节)+ length(2字节) 连接过程中要附加的数据库的文件名
ChangePassword offset(2字节)+ length(2字节) ; (introduced in TDS 7.2)
SSPILong = (四字节) ; (introduced in TDS 7.2)

5、SQL Batch
数据包格式
TDS包头(8字节)+ header + sqltext

header格式
Total length 四字节 总长度(header长度包括长度本身,不包含sqltext的长度)
legth 四字节 header的长度包括长度本身
type 两字节 header类型
TransactionDescriptor
OutstandingRequestCount

sqltext为 unicode 编码 最后以0x3b 0x00 0x0a 0x00 四个字节表示结束(8.0版本才有)

6、SQL RESPONSE

SQL RESPONSE格式
TDS包头(8字节)+ token + text

服务器对客户端的返回报文根据TDS包头的TYPE是否为0x04判断
根据TDS包头后的第一个字节TokenType判断回复的消息类型

TokenType 类型 描述
0xFD DONE 指示SQL语句的完成状态
0x81 COLMETADATA 描述返回列数据的类型和长度
0xFF DONEINPROC 指示存储过程中SQL语句的完成状态
0xFE DONEPROC 指示存储过程的完成状态。这也是为通过SQL语句执行的存储过程生成的。
0xE3 ENVCHANGE 环境更改的通知(例如,数据库、语言等)。
0xAA ERROR 错误信息
0xAE FEATUREEXTACK 在TDS 7.4中引入了FEATUREEXTACK,它用于向客户端发送一个可选的确认消息,以提供在FeatureExt中定义的特性。
0xAB INFO 向客户端发送信息消息
0xAD LOGINACK 登录回复
0xD2 NBCROW TDS7.3.B引进,用于将COLMETADATA令牌定义的行发送到具有空位图压缩的客户端
0x78 OFFSET removed in TDS 7.2 用于通知客户端在客户端的SQL文本缓冲区中出现了一个特定的关键字
0xA9 ORDER 用于通知客户端数据被排序的列
0x79 RETURNSTATUS 用于将RPC的状态值发送给客户机和T-SQL EXEC查询的结果状态值。
0xD1 ROW 用于向客户端发送由COLMETADATA令牌定义的完整行
0xE4 SESSIONSTATE 用于向客户端发送会话状态数据
0xED SSPI 在登录过程中返回的SSPI令牌

Pre-Login Response比较特殊没有TokenType,TDS包头之后的第一个字节应该是版本号相关
如果小于8可判定为Pre-Login Response报文。

6.1 DONE格式
字段 长度 描述
TokenType 一字节 0xFD
Status 两字节 0x00表示此消息最终完成消息,0x01此消息后面还有数据流,0x02当前SQL语句发生错误。
0x04事务正在进行中,0x100当前SQL语句发生错误时,用于替换DONE_ERROR
CurCmd 两字节 当前SQL语句的标记
DoneRowCount 四字节
八字节(7.2版本) 受SQL语句影响的行数

6.2 COLMETADATA格式
TokenType 一字节 0x81
Count 两字节 返回列的计数,0xFFFF和0表示没有列数据返回
接着是如下格式因为不需要之后的数据所以省略
UserType = USHORT/ULONG; (Changed to ULONG in TDS 7.2)
fNullable = BIT
fCaseSen = BIT
usUpdateable = 2BIT ; 0 = ReadOnly ; 1 = Read/Write ; 2 = Unused
fIdentity = BIT
fComputed = BIT ; (introduced in TDS 7.2)
usReservedODBC = 2BIT ; (only exists in TDS 7.3.A and below)
fSparseColumnSet = BIT ; (introduced in TDS 7.3.B)
fEncrypted = BIT ; (introduced in TDS 7.4)
usReserved3 = BIT ; (introduced in TDS 7.4)
fFixedLenCLRType = BIT ; (introduced in TDS 7.2)
usReserved = 4BIT
fHidden = BIT ; (introduced in TDS 7.2)
fKey = BIT ; (introduced in TDS 7.2)
fNullableUnknown = BIT ; (introduced in TDS 7.2)
Flags = fNullable
fCaseSen
usUpdateable
fIdentity
(FRESERVEDBIT / fComputed)
usReservedODBC
(FRESERVEDBIT / fFixedLenCLRType)
(usReserved / (FRESERVEDBIT fSparseColumnSet fEncrypted usReserved3)) ; (introduced in TDS 7.4)
(FRESERVEDBIT / fHidden)
(FRESERVEDBIT / fKey)
(FRESERVEDBIT / fNullableUnknown)
NumParts = BYTE ; (introduced in TDS 7.2)
PartName = US_VARCHAR ; (introduced in TDS 7.2)
TableName = NumParts 1*PartName
ColName = B_VARCHAR
BaseTypeInfo = TYPE_INFO ; (BaseTypeInfo introduced in TDS 7.4)
EncryptionAlgo = BYTE ; (EncryptionAlgo introduced in TDS 7.4)
AlgoName = B_VARCHAR ; (introduced in TDS 7.4)
EncryptionAlgoType = BYTE ; (introduced in TDS 7.4)
NormVersion = BYTE ; (introduced in TDS 7.4)
Ordinal = USHORT ; (introduced in TDS 7.4)
CryptoMetaData = Ordinal ; (CryptoMetaData introduced in TDS 7.4)
UserType
BaseTypeInfo
EncryptionAlgo
[AlgoName]
EncryptionAlgoType
NormVersion
EkValueCount = USHORT ; (introduced in TDS 7.4)
CekTable = EkValueCount ; (introduced in TDS 7.4)
*EK_INFO ; (introduced in TDS 7.4)
ColumnData = UserType
Flags
TYPE_INFO
[TableName]
[CryptoMetaData]
ColName
NoMetaData = %xFF %xFF

6.3 DONEINPROC格式
字段 长度 描述
TokenType 一字节 0xFF
Status 两字节 0x00表示此消息最终完成消息,0x01此消息后面还有数据流,0x02当前SQL语句发生错误。
0x04事务正在进行中,0x100当前SQL语句发生错误时,用于替换DONE_ERROR
CurCmd 两字节 当前SQL语句的标记
DoneRowCount 四字节
八字节(7.2版本) 受SQL语句影响的行数

6.4 DONEPROC格式
字段 长度 描述
TokenType 一字节 0xFE
Status 两字节 0x00表示此消息最终完成消息,0x01此消息后面还有数据流,0x02当前SQL语句发生错误。
0x04事务正在进行中,0x100当前SQL语句发生错误时,用于替换DONE_ERROR
CurCmd 两字节 当前SQL语句的标记
DoneRowCount 四字节
八字节(7.2版本) 受SQL语句影响的行数

6.5 ENVCHANGE格式
字段 长度 描述
TokenType 一字节 0xE3
Length 两字节 ENVCHANGE数据流(EnvValueData)的总长度
Type 一字节 更改的环境变量类型
newlength 一字节 新的环境变量的长度
newdata 不定长 新的环境变量
oldlength 一字节 旧的环境变量的长度
olddata 不定长 旧的环境变量

6.6 ERROR格式
字段 长度 描述
TokenType 一字节 0xAA
Length 两字节 错误信息的长度
Number 四字节 错误码
State 一字节 错误状态和错误码对应
Class 一字节 错误的类别(严重程度)
MsgTextlen 两字节 错误信息的长度
MsgText 不定长 错误信息
ServerNamelen 一字节 服务器名称长度
ServerName 不定长 服务器名称
ProcNamelen 一字节 存储过程名称长度
ProcName 不定长 存储过程名称
LineNumber 两字节
四字节(7.2版本) 导致错误的SQL批处理或存储过程中的行号。行号从1开始。如果行号不适用于消息,则LineNumber值为0

6.7 FEATUREEXTACK格式
字段 长度 描述
TokenType 一字节 0xAE
FeatureId 一字节 特性的唯一标识符号
FeatureAckDataLen 四字节 FeatureAckData的长度
FeatureAckData 不定长 特定特性的确认数据

6.8 INFO格式
字段 长度 描述
TokenType 一字节 0xAB
Length 两字节 错误信息的长度
Number 四字节 错误码
State 一字节 错误状态和错误码对应
Class 一字节 错误的类别(严重程度)
MsgTextlen 两字节 错误信息的长度
MsgText 不定长 错误信息
ServerNamelen 一字节 服务器名称长度
ServerName 不定长 服务器名称
ProcNamelen 一字节 存储过程名称长度
ProcName 不定长 存储过程名称
LineNumber 两字节
四字节(7.2版本) 导致错误的SQL批处理或存储过程中的行号。行号从1开始。如

6.9、LOGINACK格式
字段 长度 描述
TokenType 一字节 0xAD
Length 两字节 Interface, TDSVersion, Progname,ProgVersion字段的总长度
Interface 一字节 服务器接受客户端请求的接口类型
TDSVersion 四字节 服务器使用的TDS版本
ProgName 不定长(一字节长度+数据) 服务端程序名称
ProgVersion 四字节 服务端程序版本

6.10、NBCROW格式
字段 长度 描述
TokenType 一字节 0xD2
TextPointer 一字节长度+数据 数据的指针和指针的长度
Timestamp 八字节 时间戳
Data 不定长 列的实际数据

6.11、OFFSET格式
字段 长度 描述
TokenType 一字节 0x78
Identifier 两字节 OffSetLen引用的关键字
OffsetLen 两字节 标识符的服务器接收到的SQL文本缓冲区中的偏移量

6.12、ORDER格式
字段 长度 描述
TokenType 一字节 0xA9
Length 两字节 ORDER data长度
ColNum 不定长 结果集中的列号

6.13、RETURNSTATUS格式
字段 长度 描述
TokenType 一字节 0x79

6.14、ROW格式
字段 长度 描述
TokenType 一字节 0xD1
TextPointer 一字节长度+数据 数据的指针和指针的长度
Timestamp 八字节 时间戳
Data 不定长 列的实际数据

6.15、SESSIONSTATE格式
字段 长度 描述
TokenType 一字节 0xE4
Length 四字节 长度不包括TokenType和长度
SeqNo 四字节 连接中的会话状态令牌的序号。这个数字从0开始,每次增加一个
Status 一字节 会话StateId的状态
StateId 一字节 会话状态的标识号
StateLen 一字节 相应状态的长度(以字节为单位)
StateValue 不定长 会话状态的值。这可以是任何任意数据,只要服务器理解它

6.16、SSPI格式
字段 长度 描述
TokenType 一字节 0xED
SSPIBuffer 两字节长度+数据 SSPI缓冲区长度和数据

7、SSPI
SSPI请求格式
TDS包头(8字节)+ SSPIData

8、Transaction manager request(事务管理请求)
Transaction manager request格式
TDS包头(8字节)+ header + data

转载自原文链接, 如需删除请联系管理员。

原文链接:tds协议详细解析,转载请注明来源!

0