From 80a912421a065bfeacc8bf7295ddbb95b04aa113 Mon Sep 17 00:00:00 2001 From: hongjl <89757630@qq.com> Date: Thu, 9 May 2019 09:45:04 +0800 Subject: [PATCH] support goroutine connect to multi devices --- client.go | 12 +++++--- multi.go | 6 ++-- tcpclient.go | 6 ++-- test/tcpclient_test.go | 63 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 8 deletions(-) diff --git a/client.go b/client.go index 51d840d..ed5488f 100644 --- a/client.go +++ b/client.go @@ -49,9 +49,9 @@ const ( ) //PDULength variable to store pdu length after connect -var PDULength int //global variable pdulength +//var tt, _ := mb.transporter.(*tcpTransporter)tt, _ := mb.transporter.(*tcpTransporter) int //global variable pdulength -// ClientHandler is the interface that groups the Packager and Transporter methods. +// CliePDULengthntHandler is the interface that groups the Packager and Transporter methods. type ClientHandler interface { Packager Transporter @@ -184,7 +184,10 @@ func (mb *client) readArea(area int, dbNumber int, start int, amount int, wordLe wordLen = s7wlbyte } } - maxElements = (PDULength - 18) / wordSize // 18 = Reply telegram header //lth note here + + tt, _ := interface{}(mb.transporter).(*TCPClientHandler) + + maxElements = (tt.PDULength - 18) / wordSize // 18 = Reply telegram header //lth note here totElements = amount for totElements > 0 && err == nil { numElements = totElements @@ -278,7 +281,8 @@ func (mb *client) writeArea(area int, dbnumber int, start int, amount int, wordl wordlen = s7wlbyte } } - maxElements = (PDULength - 35) / wordSize // 35 = Reply telegram header + tt, _ := interface{}(mb.transporter).(*TCPClientHandler) + maxElements = (tt.PDULength - 35) / wordSize // 35 = Reply telegram header totElements = amount for totElements > 0 && err == nil { numElements = totElements diff --git a/multi.go b/multi.go index e337a24..6351771 100644 --- a/multi.go +++ b/multi.go @@ -87,8 +87,9 @@ func (mb *client) AGWriteMulti(dataItems []S7DataItem, itemsCount int) (err erro offset = offset + itemDataSize + 4 dataLength = dataLength + itemDataSize + 4 } + tt, _ := interface{}(mb.transporter).(*TCPClientHandler) //Checks the size - if offset > PDULength { + if offset > tt.PDULength { err = fmt.Errorf(ErrorText(errCliSizeOverPDU)) return } @@ -156,7 +157,8 @@ func (mb *client) AGReadMulti(dataItems []S7DataItem, itemsCount int) (err error s7Multi = append(s7Multi, s7Item...) offset += len(s7Item) } - if offset > PDULength { + tt, _ := interface{}(mb.transporter).(*TCPClientHandler) + if offset > tt.PDULength { err = fmt.Errorf(ErrorText(errCliSizeOverPDU)) return } diff --git a/tcpclient.go b/tcpclient.go index 9fd101f..144b2c4 100644 --- a/tcpclient.go +++ b/tcpclient.go @@ -83,6 +83,8 @@ type tcpTransporter struct { remoteTSAPHigh, remoteTSAPLow byte ConnectionType int LastPDUType byte + + PDULength int } func (mb *tcpTransporter) setConnectionParameters(address string, localTSAP uint16, remoteTSAP uint16) { @@ -221,8 +223,8 @@ func (mb *tcpTransporter) negotiatePduLength() error { length := len(response) if length == 27 && response[17] == 0 && response[18] == 0 { // 20 = size of Negotiate Answer // Get PDU Size Negotiated - PDULength = int(binary.BigEndian.Uint16(response[25:])) - if PDULength <= 0 { + mb.PDULength = int(binary.BigEndian.Uint16(response[25:])) + if mb.PDULength <= 0 { err = fmt.Errorf(ErrorText(errCliNegotiatingPDU)) } } else { diff --git a/test/tcpclient_test.go b/test/tcpclient_test.go index 1eeb71b..0fab7d0 100644 --- a/test/tcpclient_test.go +++ b/test/tcpclient_test.go @@ -10,6 +10,8 @@ import ( "time" "../../gos7" + "sync" + "fmt" ) const ( @@ -28,3 +30,64 @@ func TestTCPClient(t *testing.T) { client := gos7.NewClient(handler) ClientTestAll(t, client) } + +func TestMultiTCPClient(t *testing.T) { + var handlers sync.Map + var clients sync.Map + + tcpDevices := make([]map[string]string, 2) + tcpDevices[0] = make(map[string]string, 1) + tcpDevices[1] = make(map[string]string, 1) + tcpDevices[0]["tcpDevice"] = "192.168.10.19:102" + tcpDevices[1]["tcpDevice"] = "192.168.10.10:102" + + c := make(chan int) + + for k := range tcpDevices { + go func(device map[string]string) { + handler := gos7.NewTCPClientHandler(tcpDevice, rack, slot) + handler.Timeout = 200 * time.Second + handler.IdleTimeout = 200 * time.Second + handler.Logger = log.New(os.Stdout, "tcp: ", log.LstdFlags) + handler.Address = device["tcpDevice"] + handler.Connect() + handlers.Store(device["tcpDevice"], handler) + + client := gos7.NewClient(handler) + clients.Store(device["tcpDevice"], client) + + c <- 1 + }(tcpDevices[k]) + } + + var cS []int + + for n := range c { + cS = append(cS, n) + if len(cS) == len(tcpDevices) { + close(c) + break + } + } + + cli, exist := clients.Load("192.168.10.10:102") + client, ok := cli.(gos7.Client) + if exist && ok { + buf := make([]byte, 255) + client.AGReadDB(200, 34, 4, buf) + var s7 gos7.Helper + var result float32 + s7.GetValueAt(buf, 0, &result) + fmt.Printf("%v\n", result) + } + + defer func() { + handlers.Range(func(key, value interface{}) bool { + h, _ := handlers.Load(key) + if hh, ok := h.(*gos7.TCPClientHandler); ok { + hh.Close() + } + return true + }) + }() +}