ms sqlserver & sap ase 数据库server-client通讯协议 TDS

简介:

Tabular Data Stream (TDS) 是 ms sqlserver 和 SAP ASE 客户端和数据库服务器之间通讯的协议,TDS 是一个在不断“进化”的协议,目前微软 sql server 和 SAP ASE 使用的最新版本如下

DBMS Engine VersionsTDSVER or -V ValueTDS Protocol Version in useTDS Protocol Version preferred by DBMS Engine
Sybase ASE 16.x5.05.05.0
Microsoft SQL Server 2017 (v14.00.x)10.0 or 7.37.37.4

版本的更新通常意味着增加新的数据类型,或者增加新的协议 token.
在使用 freetds 时,如果使用 sap ase 需要制定版本为 5.0,或者使用 auto,自动选择版本。

TDS & PDU:

一个 TDS 的请求或者响应可能包含多个 PDU,但是每一个 PDU 都是 PDU Header + PDU Data(可无) 构成。

A TDS packet that is longer than 512 bytes is split on the 512 byte boundary and the "more packets" bit is set.(default setting, TDS 7.0+, default 4096 bytes)

A TDS request or response may span multiple PDUs. The size of the PDU sent over the 
transport connection is negotiated at dialog establishment time. Each PDU contains a 
header, which is usually followed by data.

PDU Header

Every informations in TDS protocol (query, RPCs, responses and so on) is splitted in packets.
All packets start with the following 8 byte header.

 INT8       INT8          INT16      4 bytes
+----------+-------------+----------+--------------------+
|  packet  | last packet |  packet  |    unknown         |
|   type   |  status     |   size   |                    |
+----------+-------------+----------+--------------------+
A PDU header contains information about the size and contents of the PDU as well as an 
indication if it is the last PDU in a request or response.

packet type:
TDS 是一个基于 token的协议, packet type 表示这个 packet的类型,例如:

DefineValueDescription
TDS_BUF_LANG1The buffer contains a language command. TDS does not specify the syntax of the language command. e.g. “select * from t1”
TDS_BUF_ERROR10A resource error was detected while attempting to setup or use a logical channel. This buffer is a header only and does not contain any data
TDS_BUF_NORMAL15This packet contains a tokenized TDS request or response.

packet status:

DefineValueDescription
TDS_BUFSTAT_EOM0x01This is the last buffer in a request or a response.
TDS_BUFSTAT_SEAL0x01The buffer is encrypte

packet length:

Length is the size of the buffer including the eight bytes in the buffer header. 
It is the number of bytes from the start of this header to the start of the next buffer 
header. For example, if there are 504 bytes of data in the buffer, Length will be 512. 
Length is a two-byte, unsigned integer. Regardless of the hardware architecture of 
either the server or the client, Length is represented by <MSB, LSB>. The most 
significant byte is first, followed by the least significant byte

header 中其他字节可用于 multiplexing,因为 sql 的一个连接通常表示一个session,client 发送请求后,一般需要等待 server 返回结果,这时,该连接就不能用于其他请求发送。
但是,当应用层协议增加 channel,packet no., window 等字段时,就可以通过在应用层将多个连接通过channel 区分,实现多路复用。header中其他字段,就可以表示 channel, packet no. 等等。

PDU Data:

根据 header 中的 packet type 来解释其为哪一种 packet,如果该 packet 包含 token,再根据不同的 token 来解释其中的数据, 例如
Packet Type 为 0x0F,PDU Data Token 为 0x21,表示其为一个command,长度为20,内容为 “select * from t333”

PDU Header
  TDS Packet Type [1]:          BUF_NORMAL (0x0F)
  Status [1]:                   BUFSTAT_EOM (0x01)
  Length [2]:                   33
  Channel [2]:                  0
  Packet No. [1]:               0
  Window [1]:                   0

LANGUAGE Token (0x21); variable length.
  Length [4]:                   20
  Status [1]:                   UNUSED (0x00)
  Text Length [0]:              [19]
  Text [19]:                    "select * from t333

这是对应的 response:

c1 (int)c2 (text)
9null
PDU Header
  TDS Packet Type [1]:          BUF_RESPONSE (0x04)
  Status [1]:                   BUFSTAT_EOM (0x01)
  Length [2]:                   60
  Channel [2]:                  0
  Packet No. [1]:               0
  Window [1]:                   0

ROWFMT Token (0xEE);
  Length [2]:                   33
  Number of Columns [2]:        2
  Column 1
    Name Length [1]:            2
    Name [2]:                   "c1"
    Status [1]:                 ROW_UPDATABLE + ROW_NULLALLOWED (0x30)
    User Type [4]:              7
    Data Type [1]:              INTN
    Length [1]:                 4
    Locale Length [1]:          0
  Column 2
    Name Length [1]:            2
    Name [2]:                   "c2"
    Status [1]:                 ROW_UPDATABLE + ROW_NULLALLOWED (0x30)
    User Type [4]:              19
    Data Type [1]:              TEXT
    Length [4]:                 65536
    Locale Length [1]:          0

ROW Token (0xD1); variable length.
  Column 1
    Length [1]:                 4
    Row data [4]:               9 (0x00000009)
  Column 2
    Length [4]:                 0
    Row data [0]:               [null]

DONE Token (0xFD); fixed length.
  Length [0]:                   [8]
  Status [2]:                   DONE_COUNT (0x0010)
  TranState [2]:                TDS_TRAN_SUCCEED (0x0002)
  Count [4]:                    1

当 packet type 为 0x02 时,其 PDU Data 就全部解释为 login 的数据,没有 token,例如 :

PDU Header
  TDS Packet Type [1]:          BUF_LOGIN (0x02)
  Status [1]:                   BUFSTAT_BEGIN (0x00)
  Length [2]:                   512
  Channel [2]:                  0
  Packet No. [1]:               0
  Window [1]:                   0

PDU Header
  TDS Packet Type [1]:          BUF_LOGIN (0x02)
  Status [1]:                   BUFSTAT_EOM (0x01)
  Length [2]:                   107
  Channel [2]:                  0
  Packet No. [1]:               0
  Window [1]:                   0

Login Record; fixed length.
  Host Name [30]:               "linux-zcrv"
  Host Name Length [1]:         10
  User Name [30]:               "sa"
  User Name Length [1]:         2
  Password [30]:                "<masked>"
  Password Length [1]:          <masked> (0x00)
  Host Process [30]:            "13235"
  Host Process Length [1]:      5
  Byte Ordering - int2 [1]:     3
  Byte Ordering - int4 [1]:     1
  Character Encoding [1]:       6
  Float Format [1]:             10
  Date Format [1]:              9
  lusedb [1]:                   0x01
  ldmpld [1]:                   1
  linterfacespare [1]:          0x00
  Dialog Type [1]:              0
  lbufsize [1]:                 0
  spare [3]:                    0x000000
  Application Name [30]:        "isql"
  Application Name Length [1]:  4
  Service Name [30]:            "testserver4"
  Service Name Length [1]:      11
  Password Length [1]:          <masked> (0x00)
  TDS Version [4]:              5.0.0.0
  Prog Name [10]:               "CT-Library"
  Prog Name Length [1]:         10
  Prog Version [4]:             16.0.3.9
  Convert Shorts [1]:           0
  4-byte Float Format [1]:      13
  4-byte Date Format [1]:       17
  Language [30]:                "us_english"
  Language Length [1]:          10
  Notify when Changed [1]:      0
  Old Secure Info [2]:          0x0000
  Secure Login Flags [1]:       UNUSED (0x00)
  Bulk Copy [1]:                0
  HA Login Flags [1]:           0x08
  HA Session ID [6]:            0x000000000000
  Spare [2]:                    0x0000
  Character Set [30]:           "utf8"
  Character Set Length [1]:     4
  Notify when Changed [1]:      0
  Packet Size [6]:              512
  Packet Size Length [1]:       3
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值