func (mb *tcpTransporter) Send(request []byte) (response []byte, err error) {
	mb.mu.Lock()
	defer mb.mu.Unlock()
	// Set timer to close when idle
	mb.lastActivity = time.Now()
	mb.startCloseTimer()
	// Set write and read timeout
	var timeout time.Time
	if mb.Timeout > 0 {
		timeout = mb.lastActivity.Add(mb.Timeout)
	}
	if mb.conn == nil {
		err = fmt.Errorf("Connection to address %s is null", mb.Address)
		return
	}
	if err = mb.conn.SetDeadline(timeout); err != nil {
		return
	}
	// Send data
	mb.logf("s7: sending % x", request)
	if _, err = mb.conn.Write(request); err != nil {
		return
	}
	done := false
	data := make([]byte, tcpMaxLength)
	length := 0
	for !done && err == nil {
		// Get TPKT (4 bytes)
		if _, err = io.ReadFull(mb.conn, data[:4]); err != nil {
			log.Printf("%T %+v", err, err)
			return
		}
		// Read length, ignore transaction & protocol id (4 bytes)
		length = int(binary.BigEndian.Uint16(data[2:]))
		if length == isoHSize {
			_, err = io.ReadFull(mb.conn, data[4:7])
			if err != nil { // Skip remaining 3 bytes and Done is still false
				return
			}
		} else {
			if length > pduSizeRequested+isoHSize || length < minPduSize {
				err = fmt.Errorf("s7: invalid pdu")
				return
			}
			done = true
		}
	}
	// Skip remaining 3 COTP bytes
	_, err = io.ReadFull(mb.conn, data[4:7])
	if err != nil {
		return
	}
	mb.LastPDUType = data[5] // Stores PDU Type, we need it
	// Receives the S7 Payload
	_, err = io.ReadFull(mb.conn, data[7:length])
	if err != nil {
		return
	}
	response = data[0:length]
	mb.logf("s7: received % x\n", response)
	return
}
// Send sends data to server and ensures response length is greater than header length.
Send sends data to server and ensures response length is greater than header length.
// Send sends data to server and ensures response length is greater than header length .
func (mb *tcpTransporter) Send(request []byte) (response []byte, err error) {
	mb.mu.Lock()
	defer mb.mu.Unlock()
	mb.lastActivity = time.Now()
	mb.startCloseTimer()
	var timeout time.Time
	if mb.Timeout > 0 {
		timeout = mb.lastActivity.Add(mb.Timeout)
	}
	if mb.conn == nil {
		err = fmt.Errorf("Connection to address %s is null", mb.Address)
		return
	}
	if err = mb.conn.SetDeadline(timeout); err != nil {
		return
	}
	mb.logf("s7: sending % x", request)
	if _, err = mb.conn.Write(request); err != nil {
		return
	}
	done := false
	data := make([]byte, tcpMaxLength)
	length := 0
	for !done && err == nil {
		if _, err = io.ReadFull(mb.conn, data[:4]); err != nil {
			log.Printf("%T %+v", err, err)
			return
		}
		length = int(binary.BigEndian.Uint16(data[2:]))
		if length == isoHSize {
			_, err = io.ReadFull(mb.conn, data[4:7])
			if err != nil { 
				return
			}
		} else {
			if length > pduSizeRequested+isoHSize || length < minPduSize {
				err = fmt.Errorf("s7: invalid pdu")
				return
			}
			done = true
		}
	}
	_, err = io.ReadFull(mb.conn, data[4:7])
	if err != nil {
		return
	}
	mb.LastPDUType = data[5] 
	_, err = io.ReadFull(mb.conn, data[7:length])
	if err != nil {
		return
	}
	response = data[0:length]
	mb.logf("s7: received % x\n", response)
	return
}
func ( mb * tcpTransporter ) Send ( request [ ] byte ) ( response [ ] byte , err error ) { mb . mu . Lock ( ) defer mb . mu . Unlock ( ) mb . lastActivity = time . Now ( ) mb . startCloseTimer ( ) var timeout time . Time if mb . Timeout > 0 { timeout = mb . lastActivity . Add ( mb . Timeout ) } if mb . conn == nil { err = fmt . Errorf ( " " , mb . Address ) return } if err = mb . conn . SetDeadline ( timeout ) ; err != nil { return } mb . logf ( " " , request ) if _ , err = mb . conn . Write ( request ) ; err != nil { return } done := false data := make ( [ ] byte , tcpMaxLength ) length := 0 for ! done && err == nil { if _ , err = io . ReadFull ( mb . conn , data [ : 4 ] ) ; err != nil { log . Printf ( " " , err , err ) return } length = int ( binary . BigEndian . Uint16 ( data [ 2 : ] ) ) if length == isoHSize { _ , err = io . ReadFull ( mb . conn , data [ 4 : 7 ] ) if err != nil { return } } else { if length > pduSizeRequested + isoHSize || length < minPduSize { err = fmt . Errorf ( " " ) return } done = true } } _ , err = io . ReadFull ( mb . conn , data [ 4 : 7 ] ) if err != nil { return } mb . LastPDUType = data [ 5 ] _ , err = io . ReadFull ( mb . conn , data [ 7 : length ] ) if err != nil { return } response = data [ 0 : length ] mb . logf ( " \n " , response ) return }
Send sends data to server and ensures response length is greater than header length.
Send sends data to server and ensures response length is greater than header length .
// Set timer to close when idle // Set write and read timeout // Send data // Get TPKT (4 bytes) // Read length, ignore transaction & protocol id (4 bytes) // Skip remaining 3 bytes and Done is still false // Skip remaining 3 COTP bytes // Stores PDU Type, we need it // Receives the S7 Payload