函数:newTCPTransport
1func newTCPTransport(socket net.Conn, timeout time.Duration, customLogger *log.Logger) (tt *tcpTransport) {
2 tt = &tcpTransport{
3 socket: socket,
4 timeout: timeout,
5 logger: newLogger(fmt.Sprintf("tcp-transport(%s)", socket.RemoteAddr()), customLogger),
6 }
7 return
8}
- 这是一个构造函数,用于创建新的
tcpTransport
实例。 - 将给定的
socket
和timeout
分配给新实例的相应字段。 - 使用
newLogger
函数创建一个新的日志记录器,其中日志的前缀包含 TCP 套接字的远程地址。 - 返回新创建的
tcpTransport
实例。
函数:Close
1func (tt *tcpTransport) Close() (err error) {
2 err = tt.socket.Close()
3 return
4}
- 这个方法尝试关闭
tcpTransport
的 TCP 套接字。 - 返回关闭操作的结果,即错误
err
(如果有)。
函数:ExecuteRequest
1func (tt *tcpTransport) ExecuteRequest(req *pdu) (res *pdu, err error) {
2 err = tt.socket.SetDeadline(time.Now().Add(tt.timeout))
3 if err != nil {
4 return
5 }
6 tt.lastTxnId++
7 _, err = tt.socket.Write(tt.assembleMBAPFrame(tt.lastTxnId, req))
8 if err != nil {
9 return
10 }
11 res, err = tt.readResponse()
12 return
13}
- 设置套接字的 I/O 截止时间,确保读/写操作在指定的超时时限内完成。
- 递增事务 ID(
tt.lastTxnId
)。 - 使用
assembleMBAPFrame
方法将给定的 PDUreq
转换为一个 MBAP 帧,然后写入 TCP 套接字。 - 使用
readResponse
方法从套接字中读取响应。 - 返回读取到的响应和任何遇到的错误。
函数:ReadRequest
1func (tt *tcpTransport) ReadRequest() (req *pdu, err error) {
2 err = tt.socket.SetDeadline(time.Now().Add(tt.timeout))
3 if err != nil {
4 return
5 }
6 req, _, err = tt.readMBAPFrame()
7 if err != nil {
8 return
9 }
10 tt.lastTxnId = txnId
11 return
12}
- 设置套接字的 I/O 截止时间。
- 使用
readMBAPFrame
从套接字读取一个 MBAP 帧。 - 将读取的事务 ID 存储在
tt.lastTxnId
中。 - 返回读取的请求和任何遇到的错误。
函数:WriteResponse
1func (tt *tcpTransport) WriteResponse(res *pdu) (err error) {
2 _, err = tt.socket.Write(tt.assembleMBAPFrame(tt.lastTxnId, res))
3 return
4}
- 使用
assembleMBAPFrame
方法将给定的 PDUres
转换为一个 MBAP 帧。 - 将这个帧写入 TCP 套接字。
- 返回任何遇到的错误。
函数:readResponse
1func (tt *tcpTransport) readResponse() (res *pdu, err error) {
2 for {
3 res, txnId, err = tt.readMBAPFrame()
4 if err == ErrUnknownProtocolId {
5 continue
6 }
7 if err != nil {
8 return
9 }
10 if tt.lastTxnId != txnId {
11 tt.logger.Warningf("received unexpected transaction id (expected 0x%04x, received 0x%04x)", tt.lastTxnId, txnId)
12 continue
13 }
14 break
15 }
16 return
17}
- 在一个无限循环中读取 MBAP 帧,直到找到一个与
tt.lastTxnId
匹配的事务 ID。 - 如果遇到未知的协议 ID 错误,继续循环并尝试读取下一个帧。
- 如果遇到其他错误,返回错误。
- 如果接收到的事务 ID 与预期的事务 ID 不匹配,记录一个警告并
继续循环。 5. 如果找到匹配的事务 ID,跳出循环并返回响应。