-
Feb 8th, 2018, 12:28 PM
#1
Thread Starter
Addicted Member
TCP communication
Hi,
I have TCPIP connection using TCPclient and TCPlistener in a seperate thread.
It works fine if I allways open a new client after each roundtrip (sending /recieving or recieving /sending).
I wonder how I could keep the connection open and constantly exchange data.
server side
Code:
while true
While not server.pending
end while
dim client as TcpClient = server.AcceptTcpClient()
Dim stream as NetworkStream = client.GetStream()
...get the data and send out new data in msg...
stream.Write(msg.0,msg.Length)
client.Close()
end while
Client
Code:
Dim client As New TcpClient(IP,Port)
dim stream as NetworkStream= client.GetStream()
..prepare data...
stream.write(data,0,data.Length)
'Get the requested data
While Not stream.DataAvailble
Sleep(200)
End While
While stream.DataAvailable
Dim bytes As Int32 = stream.Read(readbuffer, 0, readbuffer.Length)
responseData += System.Text.Encoding.ASCII.GetString(readbuffer, 0, bytes)
End While
stream.Close():client.Close()
client = New TcpClient(IP,Port)
data = System.Text.Encoding.ASCII.GetBytes("some Text")
stream=client.getStream()
stream.write(data,0,data.Length)
-
Feb 8th, 2018, 04:19 PM
#2
Re: TCP communication
I would suggest not closing the clients.
-
Feb 8th, 2018, 04:52 PM
#3
Thread Starter
Addicted Member
Re: TCP communication
I have tried it. But this does not seem to send the data. It looks like the connection had been closed, although the networkstream.canwrite and client.connected returned true.
-
Feb 8th, 2018, 05:34 PM
#4
Re: TCP communication
Rather than using synchronous methods on a dedicated thread, I would suggest using the asynchronous methods built into the types you're using. If you follow the CodeBank link in my signature below, you'll find a thread on Asynchronous TCP that demonstrates those methods.
-
Feb 8th, 2018, 06:03 PM
#5
Re: TCP communication
jmcilhinney is probably correct in that you should use asynchronous methods to implement your interfaces, although I find synchronous reads on background threads easier to write myself. Probably because I haven't tried using the asynchronous method enough.
As a quick example, I just wrote this code which ping-pongs a random sized small message (10 to 100 bytes) between two threads over TCP within the same executable (which sounds like what you may have been experimenting with?).
No controls needed on the form. Run from the IDE and it prints out to the Immediate window, (or Output window depending on IDE configuration).
Example output:
Code:
Client sent the first message to kick things off. Sent 65 bytes
Server received 65 bytes
Server sent 49 bytes
Client received 49 bytes
Client sent 64 bytes
Server received 64 bytes
Server sent 94 bytes
Client received 94 bytes
Client sent 73 bytes
Server received 73 bytes
'etc....
The receive and send code of the client is mostly the same as the receive and send code of the server.
Code:
Imports System.Net.Sockets
Imports System.Net
Imports System.Threading
Public Class Form1
'Server
Private ServerListenThread As Threading.Thread = New Threading.Thread(AddressOf Listener)
Private exiting As Boolean
Private ServerPort As Integer
'Client
Private TcpClientReceiverThread As New Threading.Thread(AddressOf ClientReceiverThread)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ServerListenThread.IsBackground = True
ServerListenThread.Start()
TcpClientReceiverThread.IsBackground = True
TcpClientReceiverThread.Start()
End Sub
#Region "Server"
Private Sub Listener()
Dim server As TcpListener
Dim nStream As NetworkStream = Nothing
Dim bLen(3) As Byte 'the len of the message being sent or received
Dim outData(100) As Byte
Dim inData(100) As Byte
Dim iLen As Int32
Dim rand As New Random
'some random data to send from
For i As Integer = 0 To 100
outData(i) = CByte(rand.Next(1, 255))
Next
server = New TcpListener(IPAddress.Any, 0) 'create a TCP server with a system assigned port
server.Start()
ServerPort = CType(server.LocalEndpoint, IPEndPoint).Port 'save the assigned port for reference
Dim lClient As TcpClient = Nothing
Try
lClient = server.AcceptTcpClient()
nStream = lClient.GetStream
Dim cnt As Integer
Do Until exiting 'Inner loop where we read the stream
cnt = nStream.Read(bLen, 0, 4) 'Read the 4-byte image length into bLen byte array
iLen = BitConverter.ToInt32(bLen, 0) 'Convert the 4 bytes into a 32-bit integer
If iLen < 100 Then 'Simply santity check of the value, don't expect more than 100 bytes
iLen = nStream.Read(inData, 0, iLen) ' Read the amount of data we expect to receive
If Not exiting Then ' Make sure the form is still there (close wasn't selected while we were waiting to read)
Debug.Print("Server received {0} bytes", iLen)
iLen = rand.Next(10, 100) 'choose to send 10 to 100 bytes the other direction
bLen = BitConverter.GetBytes(iLen) 'convert length to four bytes
nStream.Write(bLen, 0, 4) 'send length out first
nStream.Write(outData, 0, iLen) 'followed by the data
Debug.Print("Server sent {0} bytes", iLen)
End If
End If
Loop
Catch ex As Exception 'If we get an exception at any point in the process (usually a connection lost or closed)
Finally
If nStream IsNot Nothing Then nStream.Dispose()
If lClient IsNot Nothing Then lClient.Close()
End Try
server.Stop()
server = Nothing
End Sub
#End Region
#Region "Client"
Private Sub ClientReceiverThread()
Dim client As New TcpClient
Dim nStream As NetworkStream = Nothing
Dim bLen(3) As Byte 'the len of the message being sent or received
Dim outData(100) As Byte
Dim inData(100) As Byte
Dim iLen As Int32
Dim rand As New Random
'some random data to send from
For i As Integer = 0 To 100
outData(i) = CByte(rand.Next(1, 255))
Next
Do While ServerPort = 0 'Wait for Server to tell us what port to connect to
Thread.Sleep(100)
Loop
client.Connect(IPAddress.Parse("127.0.0.1"), ServerPort)
If client.Connected Then
nStream = client.GetStream
Try
'Send a message to the server to get things started.
iLen = rand.Next(10, 100) 'choose to send 10 to 100 bytes to the server
bLen = BitConverter.GetBytes(iLen) 'convert length to four bytes
nStream.Write(bLen, 0, 4) 'send length out first
nStream.Write(outData, 0, iLen) 'followed by the data
Debug.Print("Client sent the first message to kick things off. Sent {0} bytes", iLen)
Dim cnt As Integer
Do Until exiting 'Will loop, waiting for server to respond, then sending another message
cnt = nStream.Read(bLen, 0, 4) 'Read the 4-byte image length into bLen byte array
iLen = BitConverter.ToInt32(bLen, 0) 'Convert the 4 bytes into a 32-bit integer
If iLen < 100 Then 'Simply santity check of the value, don't expect more than 100 bytes
iLen = nStream.Read(inData, 0, iLen) ' Read the amount of data we expect to receive
If Not exiting Then ' Make sure the form is still there (close wasn't selected while we were waiting to read)
Debug.Print("Client received {0} bytes", iLen)
iLen = rand.Next(10, 100) 'choose to send 10 to 100 bytes the other direction
bLen = BitConverter.GetBytes(iLen) 'convert length to four bytes
nStream.Write(bLen, 0, 4) 'send length out first
nStream.Write(outData, 0, iLen) 'followed by the data
Debug.Print("Client sent {0} bytes", iLen)
End If
End If
Loop
Catch ex As Exception 'If we get an exception at any point in the process (usually a connection lost or closed)
Finally
If nStream IsNot Nothing Then nStream.Dispose()
If client IsNot Nothing Then client.Close()
End Try
client = Nothing
Else
Debug.Print("Client didn't connect. Example busted")
End If
exiting = True
End Sub
#End Region
End Class
p.s. This code was somewhat pulled form two programs that transferred bitmap data as a png image between two computers, which is why some comments mention "image".
Last edited by passel; Feb 8th, 2018 at 06:15 PM.
-
Feb 9th, 2018, 12:54 PM
#6
Thread Starter
Addicted Member
Re: TCP communication
thanks for this nice example. I think I now better understand the way to program with sockets. It works now!
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
|