|
-
Jan 9th, 2015, 06:16 AM
#1
Thread Starter
Member
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?
-
Jan 9th, 2015, 07:53 AM
#2
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|