?
Solved

How to keep a TCPClient connected on a machine with a specific port?

Posted on 2008-02-09
8
Medium Priority
?
803 Views
Last Modified: 2013-11-07
Hi experts

i use the code below to connect on a machine on port 8000
it works, i can get a response back from the server however, i cannot send another command

eg in telnet :

i connect server i get a response "you're connected'
then i type "GETSTATUS" and then the server give me back some string

with the code below, i don't know how to do this because i always have the "you're connected" and after that, i cannot do anything else

can you help me.?

regards

Dim data As Byte()
            Dim stream As NetworkStream = Nothing
            Dim client As TcpClient = Nothing
            Dim responseData As String
            Dim bytes As Int32
 
            Try
 
                client = New TcpClient()
 
                ' Translate the passed message into ASCII and store it as a Byte array.
                data = System.Text.Encoding.ASCII.GetBytes(Message)
 
                ' Get a client stream for reading and writing.
                stream = client.GetStream()
 
                If stream.CanWrite AndAlso stream.CanRead Then
                    ' Send the message to the connected TcpServer. 
                    stream.Write(data, 0, data.Length)
 
                    ' Receive the TcpServer.response.
                    ' Buffer to store the response bytes.
                    data = New [Byte](32768) {}
 
                    ' String to store the response ASCII representation.
                    responseData = String.Empty
 
 
                    ' Read the first batch of the TcpServer response bytes.
                    bytes = stream.Read(data, 0, data.Length)
                    responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes)
                    Return responseData
                Else
                    Return String.Empty
                End If
 
            Catch ex As Exception
                Return String.Empty
            Finally
                If stream IsNot Nothing Then
                    stream.Close()
                End If
                If client IsNot Nothing Then
                    client.Close()
                End If
            End Try

Open in new window

0
Comment
Question by:Dnx_7
  • 4
  • 4
8 Comments
 
LVL 14

Expert Comment

by:PockyMaster
ID: 20856878
You are closing the client after your read. You might want to keep the client instance in a member variable of your class instead and close it when you no longer need it.
0
 
LVL 2

Author Comment

by:Dnx_7
ID: 20857190
hi,

as you mentionned, i declared stream and client in class member
but the function "Connect" return true

after that, i call "GetStatus" function and in the "SendCommand" Function it is blocked at this line :

" bytes = Me._stream.Read(buffer, 0, buffer.Length)"


any ideas?

thank you

regards

        Public Sub New(ByVal Server As String, ByVal Port As Int32)
            Me._server = Server
            Me._port = Port
        End Sub
 
        Public Function Connect() As Boolean
            Dim buffer As Byte()
            Dim bytes As Int32
            Dim responseData As String
            Try
                Me._client = New TcpClient(Me._server, Me._port)
                ' Get a client stream for reading and writing.
                Me._stream = Me._client.GetStream()
                buffer = New Byte(Me._client.ReceiveBufferSize) {}
                bytes = Me._stream.Read(buffer, 0, buffer.Length)
                responseData = System.Text.Encoding.ASCII.GetString(buffer, 0, bytes)
                If responseData.Trim.ToLower.Contains("playbox") Then
                    Return True
                Else
                    Return False
                End If
            Catch ex As Exception
                Return False
            End Try
            Return True
        End Function
 
        Public Sub Disconnect()
            If Me._client IsNot Nothing Then
                Me._client.Close()
            End If
            If Me._stream IsNot Nothing Then
                Me._stream.Close()
            End If
        End Sub
 
        Private Function SendCommand(ByVal Message As String) As String
 
            Dim data As Byte()
            ' String to store the response ASCII representation.
            Dim responseData As String
            Dim bytes As Int32
 
            If Me._client.Connected AndAlso Me._stream.CanRead AndAlso Me._stream.CanWrite Then
 
                Try
 
 
                    ' Translate the passed message into ASCII and store it as a Byte array.
                    data = System.Text.Encoding.ASCII.GetBytes(Message)
 
                    If Me._stream.CanWrite AndAlso Me._stream.CanRead Then
 
                        ' Send the message to the connected TcpServer. 
                        Me._stream.Write(data, 0, data.Length)
 
                        data = New [Byte](32768) {}
                        bytes = Me._stream.Read(data, 0, data.Length)
 
                        ' Read the first batch of the TcpServer response bytes.
                        responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes)
 
                        Return responseData
 
                    Else
                        Return String.Empty
                    End If
 
                Catch ex As Exception
                    Return String.Empty
                End Try
 
            Else
                Return String.Empty
            End If
            
        End Function

Open in new window

0
 
LVL 14

Expert Comment

by:PockyMaster
ID: 20857698
yeah, read is a blocking call, if you want to do asynchronous stuff, use the beginread/beginwrite methods.
you can pass in a delegate method that will be called when needed.
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
LVL 2

Author Comment

by:Dnx_7
ID: 20857883
blocked call, i meant that the call never passed...
so i use async way with both beginRead and beginWrite...

but the second call to "read" is blocked and never came back in the application

don't understand...


 Private Sub DataSent(ByVal ar As IAsyncResult)
            Try
                Me._stream.EndWrite(ar)
                Dim b() As Byte
                b = New Byte(1024) {}
                Me._stream.BeginRead(b, 0, b.Length, AddressOf DataReceived, Nothing)
            Catch ex As Exception
 
            End Try
        End Sub
 
        Private Sub DataReceived(ByVal ar As IAsyncResult)
            Dim count As Int32 = Me._stream.EndRead(ar)
            Console.WriteLine(System.Text.Encoding.ASCII.GetString(New Byte(1024) {}, 0, count))
        End Sub
 
        Private Function SendCommand(ByVal Message As String) As String
 
            Dim data As Byte()
            data = System.Text.Encoding.ASCII.GetBytes(Message)
            Me._stream.BeginWrite(data, 0, data.Length, AddressOf DataSent, Nothing)
 
end function

Open in new window

0
 
LVL 14

Expert Comment

by:PockyMaster
ID: 20858012
http://msdn2.microsoft.com/en-us/library/bbx2eya8(VS.80).aspx

I think the beginread does not belong in your write method.
you can call the beginread again at the end of your datareceived method
0
 
LVL 2

Author Comment

by:Dnx_7
ID: 20864665
i found the problem but cannot resolve yet

in fact,

i'm connecting to the server, make a read => OK, i get a response
i'm not closing the stream and the client, i write another message to the server => ok again, i got a response
but at the third time i wrote a message... the stream got a "dataavailable" = false
that's why the read block!

what i don't understand, it's that i'm writing a new message to the server but no dataavailable???

any help?

regards
0
 
LVL 14

Accepted Solution

by:
PockyMaster earned 1500 total points
ID: 20878677
You could be starting to read earlier than the incoming message has arrived.
You can check first if you have data:


' Example of EndRead, DataAvailable and BeginRead.
Public Shared Sub myReadCallBack(ar As IAsyncResult)
 
   Dim myNetworkStream As NetworkStream = CType(ar.AsyncState, NetworkStream)
   Dim myReadBuffer(1024) As Byte
   Dim myCompleteMessage As [String] = ""
   Dim numberOfBytesRead As Integer
 
   numberOfBytesRead = myNetworkStream.EndRead(ar)
   myCompleteMessage = [String].Concat(myCompleteMessage, Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead))
 
   ' message received may be larger than buffer size so loop through until you have it all.
   While myNetworkStream.DataAvailable
 
      myNetworkStream.BeginRead(myReadBuffer, 0, myReadBuffer.Length, New AsyncCallback(AddressOf NetworkStream_ASync_Send_Receive.myReadCallBack), myNetworkStream)
   End While
 
 
   ' Print out the received message to the console.
   Console.WriteLine(("You received the following message : " + myCompleteMessage))
End Sub 'myReadCallBack

Open in new window

0
 
LVL 2

Author Comment

by:Dnx_7
ID: 20882529
yep you're right, in fact i added all checkin' stuff and in fact, the buffer need a "carriage return" and a "line feed" to send a response to the client...


now it's work,


the beginWrite works nicely but i have some difficulties for the beginRead

btw, thank you for your help
0

Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Welcome my friends to the second instalment and follow-up to our Minify and Concatenate Your Scripts and Stylesheets (http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/A_4334-Minify-and-Concatenate-Your-Scripts-and-Stylesheets.html)…
Simulator games are perfect for generating sample realistic data streams, especially for learning data analysis. It is even useful for demoing offerings such as Azure stream analytics, PowerBI etc.
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…
Enter Foreign and Special Characters Enter characters you can't find on a keyboard using its ASCII code ... and learn how to make a handy reference for yourself using Excel ~ Use these codes in any Windows application! ... whether it is a Micr…
Suggested Courses

600 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question