Re: How is this conditional able to execute?



Thanks Stephany. This is super helpful.

Why is this part out of the loop:
Dim networkStream As NetworkStream = tcpClient.GetStream()

Also, your first IF:
If networkStream.DataAvailable then

didn't have an ending END IF. I put on just before the catch. Is that
correct?

This conditional is still being executed when returndata = ""
If returndata <> "" AndAlso returndata <>
ClientForm.ReturnData Then
ClientForm.ReturnData = returndata
End If
Maybe I just don't understand the returndata = "" because of the byte array.
But it seems you are testing the same conditions I did before. So the above
will always execute because the array always has 8192 length and somehow
that makes returndata pass on returndata <> "".

How can I read the string in :
Dim returndata As String = Encoding.UTF8.GetString(bytes, 0, bytesread)
returndata gets the empty string here, although it really isn't, as have
seen previously.

thanks,
brett

"Stephany Young" <noone@localhost> wrote in message
news:eJau0ZURFHA.576@xxxxxxxxxxxxxxxxxxxxxxx
> The mist is clearing.
>
> If I've misunderstood anything please let me know because I'm still making
> some assumptions.
>
> I suspect that your starting point for the Try ... Catch ... End Try
> section is the example shown in the documentation on the
> TcpClient.GetStream method.
>
> What you have done is wrapped it in a loop and added some embellishments
> and that example was not quite designed for that to be done to it. The
> example was designed for a one-time run and to drop through the logic to
> whatever followed. In your case you want the loop to continue until
> certain conditions are met or the program ends. To meet this need you need
> to do things just a little differently.
>
> I assume that ClientForm.utility is also a shared reference to some sort
> of utiliy class and that ClientForm.Packet is declared in a similar
> fashion to ClientForm.ReturnData.
>
> If I am correct in that ConnectInit is outside the thread then you
> shouldn't be attempting to reinstate a 'broken' connection within the
> thread. If a 'broken' connection is detected you should allow the thread
> to 'die', then reconnect, then start a new instance of the thread.
>
> Before the start of loop you are obtaining a reference to the
> NetworkStream object of the TcpClient object. In addidition, on each
> iteration of the loop you are obtaining a fresh reference to the
> NetworkStream object of the TcpClient object. There is no reason to do
> this. Don't quote me on this but I suspect that doing so will cause you
> problems.
>
> The declaration of the 'bytes' array should not need to be inside the
> loop. Creating a new array on every iteration is not necessary. When you
> read the NetworkStream object, the data will overwrite what is already in
> the array. of course the array should be created with 8192 elements by
> using tcpClient.ReceiveBufferSize - 1 rather than the 8193 elements you
> will get if you simply use tcpClient.ReceiveBufferSize.
>
> The NetworkStream.Read method, as well as filling the array, also returns
> an integer indicating the number of bytes successfully read into the
> array. You should make use of this to control what you are dealing with.
> Remember that tcpClient.ReceiveBufferSize is the maximum number of bytes
> that can be read at any one time rather than the number of bytes that are
> actually read.
>
> For the third parameter to the NetworkStream.Read method, it is, in my
> opinion, better to use bytes.Length rather than
> tcpClient.ReceiveBufferSize because bytes.Length is the actual number of
> elements in the array.
>
> I think that the tests of the NetworkStream.CanWrite and
> NetworkStream.CanRead are probably redundant, unless you are opening the
> sockets at either end with specfic read/write restrictions.
>
> Another important point is that the NetworkStream.Read method will block
> until data is available. This is probably undesirable but can be
> circumvented by using the NetworkStream.DataAvailable property. This will
> allow your loop to iterate in a timely manner.
>
> Now that we know exactly how many bytes were read from the NetworkStream
> object, we can use the appropriate Encoding.GetString overload to make
> sure that our string is a representation of only those bytes. This should
> do away with the need for any 'trimming' of the resulting string.
>
> Where you have the test for NetworkStream.DataAvailable is inappropriate
> and I get the impression that you might not fully understand it's use.
>
> On the test of returndata, the .ToString is redundant because returndata
> is already a string. The parenthesis are also redundant. In addition,
> using AndAlso will be better than And here because if returndata is an
> empty string then the second part of the test will not be evaluated if
> AndAlso is used whereas it will be evaluated if just And is used. The
> logic is that if the evaluation of first part fails then why bother
> evaluating the second part at all. This is clled 'short-circuiting' and is
> a very useful technique when used appropriately. Setting returndata to
> Nothing is redundant because returndata is going to be created anew on the
> next iteration of the loop. Likewise, the 'Else' that does nothing is also
> redundant.
>
> As you can see, the resulting code is more compact and now, that the
> appropriate techniques are being used, should work quite happily.
>
> What is left to do, of course, is for you to add the appropriate code to
> 'tear-down' the thread in a friendly fashion when the program needs to
> terminate or you need to stop the thread for some other reason.
>
>
> Code as supplied by Brett
> -------------------------
>
> In ClientForm
> -------------
> Public Shared ReturnData As String
> Public Shared Packet As String ' or something like that
> Public Shared utility As UtilityClass = New UtilityClass ' or something
> like that
> -------------
>
>
> Dim ConnectAttempts As Integer = 0
> Dim t As Thread
>
> Dim Packet As String
> Dim InitialIDSent As Boolean = False
>
> Dim tsGap As TimeSpan
> Dim dtStart As DateTime = Now
>
> ConnectInit()
>
> Within thread
> -------------
> Dim networkStream As NetworkStream = tcpClient.GetStream()
>
> While True
> Try
>
> If networkStream.CanWrite And networkStream.CanRead Then
>
> networkStream = tcpClient.GetStream()
>
> Dim bytes(tcpClient.ReceiveBufferSize) As Byte
> networkStream.Read(bytes, 0, tcpClient.ReceiveBufferSize)
> Dim returndata As String =
> Trim(Encoding.UTF8.GetString(bytes).Trim(Char.MinValue))
>
> If InitialIDSent Then
> Packet = "Nothing to Write from: " & Thread.CurrentThread.Name
> Else
> Packet = "Connected: " & ClientForm.Packet
> InitialIDSent = True
> 'write to log file
>
> ClientForm.utility.WriteToFile(ClientForm.CurrentDirectory.GetCurrentDirectory,
> ClientForm.LogFileExec, ClientForm.utility.CurrentDateTime(0) & " -
> Connected: " & ClientForm.Packet)
> End If
>
> ' Do a simple write.
> Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes(Packet.TrimEnd)
> networkStream.Write(sendBytes, 0, sendBytes.Length)
>
> If networkStream.DataAvailable() Then
> If (returndata <> "") And returndata.ToString <>
> ClientForm.ReturnData Then
> ClientForm.ReturnData = returndata
> returndata = Nothing
>
> Else
> End If
> End If
>
> End If
>
> Catch ex As Exception
>
> If ex.Message = "Operation not allowed on non-connected sockets."
> Then
> ConnectInit()
> ConnectAttempts = +1
>
> If ConnectAttempts > 5 Then
> Exit Sub
> End If
> Else
> End If
> Exit While
> End Try
>
> Thread.CurrentThread.Sleep(500)
> End While
> -------------
>
>
> Code as modified by Stephany
> ----------------------------
>
> In ClientForm
> -------------
> Public Shared ReturnData As String
> Public Shared Packet As String ' or something like that
> Public Shared utility As UtilityClass = New UtilityClass ' or something
> like that
> -------------
>
>
> Dim ConnectAttempts As Integer = 0
> Dim t As Thread
>
> Dim Packet As String
> Dim InitialIDSent As Boolean = False
>
> Dim tsGap As TimeSpan
> Dim dtStart As DateTime = Now
>
> ConnectInit()
>
> Within thread
> -------------
> Dim networkStream As NetworkStream = tcpClient.GetStream()
>
> Dim bytes(tcpClient.ReceiveBufferSize - 1) As Byte
>
> Dim bytesread As Integer
>
> While True
> Try
> If networkStream.DataAvailable then
> bytesread = networkStream.Read(bytes, 0, bytes.Length)
> Dim returndata As String = Encoding.UTF8.GetString(bytes, 0,
> bytesread)
> If InitialIDSent Then
> Packet = "Nothing to Write from: " & Thread.CurrentThread.Name
> Else
> Packet = "Connected: " & ClientForm.Packet
> InitialIDSent = True
> 'write to log file
>
> ClientForm.utility.WriteToFile(ClientForm.CurrentDirectory.GetCurrentDirectory,
> ClientForm.LogFileExec, ClientForm.utility.CurrentDateTime(0) & " -
> Connected: " & ClientForm.Packet)
> End If
> ' Do a simple write.
> Dim sendBytes() As Byte = Encoding.ASCII.GetBytes(Packet.TrimEnd)
> networkStream.Write(sendBytes, 0, sendBytes.Length)
> If returndata <> "" AndAlso returndata <> ClientForm.ReturnData
> Then ClientForm.ReturnData = returndata
> End If
> Catch ex As Exception
> Exit While
> End Try
> Thread.CurrentThread.Sleep(500)
> End While
> -------------
>
>
>


.



Relevant Pages

  • Re: Looping through Query to create multiple sheets in excel- Just need the loop
    ... I always get to this point and I can't figure out how to loop through ... I have put the string in the query at the bottom. ... Optional strWorkSheet As String, Optional strRange As ... Dim objXLSheet As Object 'Excel.Worksheet ...
    (microsoft.public.access.forms)
  • RE: Follow up question. Get value of closed file.
    ... MsgBox ReturnData and it said type mismatch. ... Dim ReturnData as Variant ... SourceSheet As String, _ ... Dim rsData As Object ...
    (microsoft.public.excel.programming)
  • Re: How is this conditional able to execute?
    ... > inside the loop, then each time the loop iterates then a NEW reference to ... > Note that the test of returndata is not a type. ... Here's some of my output starting with the first iteration: ... You can see returndata is the empty string above yet your IF is executed. ...
    (microsoft.public.dotnet.languages.vb)
  • Re: How is this conditional able to execute?
    ... inside the loop, then each time the loop iterates then a NEW reference to ... Note that the test of returndata is not a type. ... Dim returndata As String = "" ... Not that 'Changing' is only displayed when returndata is NOT an empty string ...
    (microsoft.public.dotnet.languages.vb)
  • Re: How to put lines with certain text (from a file) in an array
    ... In one sense all consistent but now the Filter approach is taking about 2x longer than the loop with Instr with all sizes. ... Dim sFile As String, sText As String ...
    (microsoft.public.excel.programming)