Results 1 to 2 of 2

Thread: Multi TCP connection thread via single function, only work last connected TCP

  1. #1

    Thread Starter
    Member
    Join Date
    Aug 2014
    Posts
    32

    Smile Multi TCP connection thread via single function, only work last connected TCP

    Hi everyone,

    I'm trying to control 2 different device which normaly control via serial port, but instead I use TCP-serial
    converter because device is installed at far point. TCP-serial converter is not a big deal, just make connection
    with device address and send/receive accordingly.
    However, I have couple of Subs which are for TCP socket communcation, and use this functions from different
    thread with different 2 IP address, and it doesn't work.

    First connect 192.168.0.81, and it communicate without problem, however this connection lost as soon as
    connect another IP address 192.168.0.82 through same subs.
    I call these subs from different thread, but why it doesn't work I still don't know.
    Please give me some good hint that how can I use same function from different thread and different resource.

    This is sample code which I use:


    Code:
        Dim Const BYTES_TO_READ As Integer = 20480
        Dim readBuffer(BYTES_TO_READ) As Byte
        Dim ConnectErr As Boolean = False
        Dim RCV_Buffer As Boolean = False
        Dim RCV_BufStr As String = ""
        Dim WParam(2) As String
        Dim MyTCP As TcpClient
        Dim TCPThread as Thread
    
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
             ' Anything for form load
             ' This form contains 2 buttons(Btn1, Btn2) for start connection,
             '                            2 TextBox(RcvBox1, RcvBox2) for display received data,
             '                            2 buttons(Snd1, Snd2) for send command.
    
        End Sub
    
        ' This is make connection for Device 1
        Private Sub Btn1_Click(sender As Object, e As EventArgs) Handles Btn1.Click
    
            WizParam(0) = "192.168.0.81"
            WizParam(1) = "DEV1"
            TCPThread = New Thread(AddressOf StartTCP)
            TCPThread.Start(WizParam)
    
        End Sub
    
        ' This is make connection for Device 2
        Private Sub Btn2_Click(sender As Object, e As EventArgs) Handles Btn2.Click
    
            WizParam(0) = "192.168.0.82"
            WizParam(1) = "DEV2"
            TCPThread = New Thread(AddressOf StartTCP)
            TCPThread.Start(WizParam)
    
        End Sub
    
        ' This is send commad to Device 1
        Private Sub Snd1_Click(sender As Object, e As EventArgs) Handles Snd1.Click
    
            Dim Msg(10) as Byte
            ' whatever command, assign to msg byte array
            SendTCP(Msg)
    
        End Sub
    
        ' This is send commad to Device 2
        Private Sub Snd2_Click(sender As Object, e As EventArgs) Handles Snd2.Click
    
            Dim Msg(10) as Byte
            ' whatever command, assign to msg byte array
            SendTCP(Msg)
    
        End Sub
    
        ' Make Connection for TCP Client
        Private Sub connectTCP(ByVal WParam As Object, ByVal port As Integer)
    
            Try
                MyTCP.Connect(WParam(0), port)
                If MyTCP.Connected Then
                    MyTCP.GetStream.BeginRead(readBuffer, 0, BYTES_TO_READ, AddressOf TCPDoread, WParam(1))
                    ConnectErr = False
                Else
                    ConnectErr = True
                End If
            Catch ex As SocketException
                Console.WriteLine(ex.ToString())
                ConnectErr = True
            End Try
    
        End Sub
    
        ' Send command through TCP Connection
        Private Sub SendTCP(ByVal message As Array, ByVal ALen As Integer)
    
            ' I send serial command with Hexadecimal array to TCP connection
            Dim sw As New BinaryWriter(MyTCP.GetStream)
            sw.Write(message)
            sw.Flush()
    
        End Sub
    
        ' Receive string from device through TCP connection
        Private Sub TCPReceived(ByVal message As String, DevType As String)
    
            ' Show received message from TCP connect accrding to Device Type argument
            Select Case DevType
                Case "DEV1"
                      ' Call delegate text change routine for display message to Rcv1.Text
                Case "DEV2"
                      ' Call delegate text change routine for display message to Rcv2.Text
            End Select
    
        End Sub
    
        ' Read received buffer from TCP connection
        Private Sub TCPDoread(ByVal ar As IAsyncResult)
    
            Dim totalRead As Integer
            Dim DeviceType As String = ar.AsyncState  ' pass device name through argument
    
            If RCV_Buffer = False Then RCV_BufStr = ""
            Try
                totalRead = MyTCP.GetStream.EndRead(ar)
            Catch ex As Exception
                Console.WriteLine(ex.ToString())
                ConnectErr = True
            End Try
    
            If totalRead > 0 Then
                Dim RcvData As String = System.Text.Encoding.Default.GetString(readBuffer, 0, totalRead)
                RCV_Buffer = True
                RCV_BufStr += RcvData
                If InStr(RcvData, Chr(ETX)) > 0 Then
                    RCV_Buffer = False
                    TCPReceived(RCV_BufStr, DeviceType)
                End If
            End If
    
            Try
                ' Begin the reading again.
                MyTCP.GetStream.BeginRead(readBuffer, 0, BYTES_TO_READ, AddressOf TCPDoread, DeviceType)
            Catch ex As Exception
                Console.WriteLine(ex.ToString())
                ConnectErr = True
            End Try
    
        End Sub
    
        ' Start TCP Connection
        Private Sub StartTCP(ByVal WParam As Object)
    
            MyTCP = New TcpClient               ' Create new instance of TCP Connection
    
            Do While True
                connectTCP(WParam, 6001) ' Connect with argument (IP and Device Type)
                Do While True
                    If ConnectErr Then
                        System.Threading.Thread.Sleep(800)
                        MyTCP.Close()
                        MyTCP = New TcpClient
                        Exit Do
                    End If
                    Thread.Sleep(100)
                Loop
            Loop
    
        End Sub
    This is just simple code, basically what I make for my application.

    1. Press Btn1 for make connection with 192.168.0.81 device, start new thread.
    2. Press Snd1 for send command to device1, and it send without problem.
    3. Receive any response from device1 without any problem.
    4. Press Btn2 for make another connection with 192.168.0.82 deivce, start new thread.
    This thread is obviously different with first thread (When I check, Thread ID is different)
    5. After that, I can't communicate with device1 any more. only can use second thread, device2.

    What I've made mistake?
    How can I communicate these 2 device at the same time without problem?

  2. #2
    Frenzied Member
    Join Date
    Jul 2011
    Location
    UK
    Posts
    1,335

    Re: Multi TCP connection thread via single function, only work last connected TCP

    There seem to be a lot of mistakes in that code. And it appears you have Option Strict turned off. Never a good idea.


    As for the problem you mention, you have 2 TcpClient objects, but use only 1 variable to reference both of them. Two into one won't go.

    MyTCP will always be referencing only the latest client you create at
    Code:
    ' Start TCP Connection
    Private Sub StartTCP(ByVal WParam As Object)
    
        MyTCP = New TcpClient               ' Create new instance of TCP Connection
    You should maintain a separate reference for each TcpClient you create, and no doubt pass the relevant reference as part of your state Object in any calls to the MyTCP.GetStream.BeginRead method.

    Also be careful with your StartTCP method:
    Code:
    ' Start TCP Connection
    Private Sub StartTCP(ByVal WParam As Object)
    
        MyTCP = New TcpClient               ' Create new instance of TCP Connection
    
        Do While True
            connectTCP(WParam, 6001) ' Connect with argument (IP and Device Type)
            Do While True
    wparam references a global array. Arrays are Reference Types Any changes to the values in the global array will be reflected in wparam in that method.

    So say you set WizParam(0) = "192.168.0.81" and start your first thread (WParam(0) = "192.168.0.81").
    Then you set WizParam(0) = "192.168.0.82" and start your second thread (WParam(0) = "192.168.0.82").
    Should the first client drop its connection it will try to reconnect by connectTCP(WParam, 6001), but WParam has changed to the 2nd IP address, so it will try to connect to the wrong device.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width