dcsimg
Results 1 to 9 of 9
  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2007
    Location
    cobwebbed to PC
    Posts
    311

    Resolved [RESOLVED] NetworkStream.Read() only ever reads first five bytes?

    Hi Folks
    Im struggling along with what is essentially my first TcpClient and first .Net project.

    I have a windows forms application project with a TcpClient and NetworkStream opened OK, CanWrite and CanRead are tested True, and NetworkStream.Write() is working fine.

    However when I attempt a read I only ever seem to get the first five bytes of the data the server sends. For data less than 5 bytes long this obv. has little effect but is not very useful. There is no exception caught that might indicate the data that was read was to short, it just acts like there is only 5 bytes to be had

    The server I am communicating with is an embedded device that essentially takes a raw TCP connection on a certain port and sends the byte data out on a serial port to a microcontroller which reads the data and generates a response back out onto the serial line, to the server and thus back onto the network and becomes the data my VB TcpClient should be receiving.

    All parts of this system have been tested to be working fine, except the read from the stream - when I use the VB application the server holds the serial lines high after the first 5 bytes are recieved, preventing the uC from sending any more data, as if the server is waiting on an ACK or something... as I said, with Hyperterminal in place of the VB app it works perfectly - so frustrating!

    so I guess my question is, is there any ACK or stream flush or anything like that that my application is missing that would cause the connection to the server to make the server believe further bytes should not be sent (yet)??

    Thanks

    This is the application code - it's pretty stripped down at this point. I am working in VS2012 and 2010 for .Net 4 (the issue appear in both versions of the IDE):

    vb Code:
    1. Imports System.Text
    2. Imports System.Net
    3. Imports System.Net.Sockets
    4.  
    5. Public Class NetReadWriteTestForm
    6.     Dim defaultRemoteIpAddress As IPAddress = IPAddress.Parse("169.254.11.150")
    7.     Dim defaultRemotePort As Integer = 10001
    8.     Dim remoteEndPoint As IPEndPoint
    9.     Dim clt As New TcpClient()
    10.     Dim stm As NetworkStream
    11.     Dim eot As Byte = &H4
    12.     Dim nl As Byte = &HA
    13.  
    14.     Private Sub NetReadWriteTestForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    15.         RemoteIPBox.Text = defaultRemoteIpAddress.ToString
    16.         RemotePortBox.Text = defaultRemotePort.ToString
    17.         Me.Show()
    18.     End Sub
    19.  
    20.     Private Sub ConnectButton_Click(sender As Object, e As EventArgs) Handles ConnectButton.Click
    21.         If Not clt.Connected Then   ' Checkclient is not already connected.
    22.             clt = New TcpClient()
    23.             remoteEndPoint = New IPEndPoint(IPAddress.Parse(RemoteIPBox.Text), CInt(RemotePortBox.Text))
    24.             Try                     ' Open the client and stream.
    25.                 clt.Connect(remoteEndPoint)
    26.                 stm = clt.GetStream
    27.             Catch ex As Exception
    28.                 MessageBox.Show("Client not connected or stream not opened.")
    29.                 Return
    30.             End Try
    31.  
    32.             If Not stm.CanRead And Not stm.CanWrite Then    ' Check the stream can be read and written to.
    33.                 MessageBox.Show("Could not read or write to the new stream")
    34.                 stm.Close()
    35.                 clt.Close()
    36.                 Return
    37.             End If
    38.  
    39.             stm.ReadTimeout = 1000
    40.             ConsoleBox.AppendText("Connected." + vbNewLine)
    41.         End If
    42.  
    43.         ConnectButton.BackColor = Color.LimeGreen
    44.     End Sub
    45.  
    46.     Private Sub DisconnectButton_Click(sender As Object, e As EventArgs) Handles DisconnectButton.Click
    47.         If clt.Connected Then   ' Check client is already open.
    48.             Try                 ' Close client and stream.
    49.                 stm.Close()
    50.                 clt.Close()
    51.             Catch ex As Exception
    52.                 MessageBox.Show("Client or stream not closed.")
    53.                 Return
    54.             End Try
    55.             ConsoleBox.AppendText("Disconnected." + vbNewLine)
    56.         End If
    57.         ConnectButton.BackColor = SystemColors.Control
    58.     End Sub
    59.  
    60.     Private Sub SendButton_Click(sender As Object, e As EventArgs) Handles SendButton.Click
    61.         Dim wBuf() As Byte = Encoding.ASCII.GetBytes(CommandBox.Text & Chr(eot) & Chr(nl))
    62.         Dim rBuf(1024) As Byte    ' Expected ResponseLength not used yet.
    63.  
    64.         If clt.Connected Then
    65.             If CommandBox.Text.Length = 0 Then
    66.                 MessageBox.Show("Command box is empty." + vbNewLine + "Try Again.")
    67.                 Return
    68.             End If
    69.  
    70.             If clt.Connected Then   ' Check client is connected.
    71.                 ConsoleBox.AppendText("Data:" + Encoding.ASCII.GetString(wBuf) + vbNewLine)
    72.                 Try                 ' Write data.
    73.                     stm.Write(wBuf, 0, wBuf.Length)
    74.                 Catch ex As Exception
    75.                     MessageBox.Show("Could not write data.")
    76.                     Return
    77.                 End Try
    78.             End If
    79.  
    80.             If ResponseLengthBox.TextLength > 0 Then
    81.                 If CInt(ResponseLengthBox.Text) > 0 Then
    82.                     ConsoleBox.AppendText("Reading..." + vbNewLine)
    83.  
    84.                     Try             ' Read data.
    85.                         stm.Read(rBuf, 0, rBuf.Length)
    86.                     Catch ex As Exception
    87.                         MessageBox.Show("Could not read response.")
    88.                     End Try
    89.  
    90.                     ConsoleBox.AppendText(Encoding.ASCII.GetString(rBuf))
    91.                     ConsoleBox.AppendText(vbNewLine)
    92.                 End If
    93.             End If
    94.         Else
    95.             MessageBox.Show("Client is not connected yet.")
    96.         End If
    97.     End Sub
    98. End Class
    Last edited by wolf99; Jul 19th, 2013 at 01:48 PM.
    Thanks

  2. #2
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 2012
    Posts
    8,242

    Re: NetworkStream.Read() only ever reads first five bytes?

    There is a fundamental flaw in your logic here. Not only do you read without pausing after the send, you only read once per button click. Once the reading of the initial five bytes is done, you simply stop listening. TCP response reading is event driven. Data arrives, the DataReceived event triggers, you do something about it. This may need to occur several times before you have a complete response. You can't simply issue an ulitmatum; "Speak now or else!"
    As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"

    Reviews: "dunfiddlin likes his DataTables" - jmcilhinney

    Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!

  3. #3

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2007
    Location
    cobwebbed to PC
    Posts
    311

    Re: NetworkStream.Read() only ever reads first five bytes?

    Hi dunfiddlin,

    Thanks for your answer. The thing is there should is *more* than 5 bytes in the response, so would not even this first read show more than that??
    I get that there is asynchronous reading but surely a blocking read can be done as well? Else what is the point in even having a synchronous read method?

    Other than that how *should* one implement a read? Is there an event for "data has arrived at your connection"? What methods should I be looking at? As I mentioned, Im a bit new at this, the code I have used is based on the MSDN data on TcpClient and NetworkStream and quite a few other online examples, etc.

    Thanks
    Thanks

  4. #4
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,622

    Re: NetworkStream.Read() only ever reads first five bytes?

    In this thread is a simple file transfer app I wrote that demonstrates how to properly use the TcpClient/TcpListener classes.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  5. #5
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 2012
    Posts
    8,242

    Re: NetworkStream.Read() only ever reads first five bytes?

    The thing is there should is *more* than 5 bytes in the response, so would not even this first read show more than that??
    Evidently not. You have no control over how and when the data is transmitted. That's why you always need asynchronous reading for this kind of communication. For the rest, go see Niya's thread. All is there revealed. (Don't tell him I said that, It'll go straight to his head! )
    As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"

    Reviews: "dunfiddlin likes his DataTables" - jmcilhinney

    Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!

  6. #6
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,622

    Re: NetworkStream.Read() only ever reads first five bytes?

    Quote Originally Posted by dunfiddlin View Post
    (Don't tell him I said that, It'll go straight to his head! )
    Too late
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  7. #7

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2007
    Location
    cobwebbed to PC
    Posts
    311

    Re: NetworkStream.Read() only ever reads first five bytes?

    Hi Niya,

    Looking at your server code, to read I need to loop on the read. Following this I have replaced lines inside the read Try of the above code with the below, but the issue remains, stm.DataAvailable is only ever true once, however long I let it run for

    VB Code:
    1. Do          ' Loop forever - it doesnt matter about breaking out of loop at the moment
    2.     If stm.DataAvailable Then
    3.         numRead = stm.Read(rBuf, ofst, rBuf.Length)
    4.         ofst += numRead
    5.         ConsoleBox.AppendText(Encoding.ASCII.GetString(rBuf))
    6.      End If
    7. Loop
    Thanks

  8. #8

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2007
    Location
    cobwebbed to PC
    Posts
    311

    Re: NetworkStream.Read() only ever reads first five bytes?

    Oh for the love of cheebus!

    Over a week staring at this issue thinking I was an idiot.... One of the byte character codes I add to the bytes that are sent is 0x04, the EOT char, as part of the serial data syntax protocol... so the server received the first part of the string in the first packet which was apparently enough to start sending the response (hence the first 5 chars) but then the second packet with the EOT char in it arrived and so the server stopped sending stuff and flushed the rest of the serial data! Gaaahhhh!

    On the upside - gotta love wireshark!
    Last edited by wolf99; Jul 20th, 2013 at 09:25 AM.
    Thanks

  9. #9
    New Member
    Join Date
    Jan 2018
    Posts
    1

    Re: [RESOLVED] NetworkStream.Read() only ever reads first five bytes?

    wolf99,
    Were you ever able to get this working? I have a similar issue with the networkstream.DataAvailable never firing or firing only once. So my loop only grabs the first few bits of the text.
    Thanks
    Phix1964

Posting Permissions

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



Featured


Click Here to Expand Forum to Full Width