-
Jul 19th, 2013, 01:37 PM
#1
Thread Starter
Hyperactive Member
[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:
Imports System.Text
Imports System.Net
Imports System.Net.Sockets
Public Class NetReadWriteTestForm
Dim defaultRemoteIpAddress As IPAddress = IPAddress.Parse("169.254.11.150")
Dim defaultRemotePort As Integer = 10001
Dim remoteEndPoint As IPEndPoint
Dim clt As New TcpClient()
Dim stm As NetworkStream
Dim eot As Byte = &H4
Dim nl As Byte = &HA
Private Sub NetReadWriteTestForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
RemoteIPBox.Text = defaultRemoteIpAddress.ToString
RemotePortBox.Text = defaultRemotePort.ToString
Me.Show()
End Sub
Private Sub ConnectButton_Click(sender As Object, e As EventArgs) Handles ConnectButton.Click
If Not clt.Connected Then ' Checkclient is not already connected.
clt = New TcpClient()
remoteEndPoint = New IPEndPoint(IPAddress.Parse(RemoteIPBox.Text), CInt(RemotePortBox.Text))
Try ' Open the client and stream.
clt.Connect(remoteEndPoint)
stm = clt.GetStream
Catch ex As Exception
MessageBox.Show("Client not connected or stream not opened.")
Return
End Try
If Not stm.CanRead And Not stm.CanWrite Then ' Check the stream can be read and written to.
MessageBox.Show("Could not read or write to the new stream")
stm.Close()
clt.Close()
Return
End If
stm.ReadTimeout = 1000
ConsoleBox.AppendText("Connected." + vbNewLine)
End If
ConnectButton.BackColor = Color.LimeGreen
End Sub
Private Sub DisconnectButton_Click(sender As Object, e As EventArgs) Handles DisconnectButton.Click
If clt.Connected Then ' Check client is already open.
Try ' Close client and stream.
stm.Close()
clt.Close()
Catch ex As Exception
MessageBox.Show("Client or stream not closed.")
Return
End Try
ConsoleBox.AppendText("Disconnected." + vbNewLine)
End If
ConnectButton.BackColor = SystemColors.Control
End Sub
Private Sub SendButton_Click(sender As Object, e As EventArgs) Handles SendButton.Click
Dim wBuf() As Byte = Encoding.ASCII.GetBytes(CommandBox.Text & Chr(eot) & Chr(nl))
Dim rBuf(1024) As Byte ' Expected ResponseLength not used yet.
If clt.Connected Then
If CommandBox.Text.Length = 0 Then
MessageBox.Show("Command box is empty." + vbNewLine + "Try Again.")
Return
End If
If clt.Connected Then ' Check client is connected.
ConsoleBox.AppendText("Data:" + Encoding.ASCII.GetString(wBuf) + vbNewLine)
Try ' Write data.
stm.Write(wBuf, 0, wBuf.Length)
Catch ex As Exception
MessageBox.Show("Could not write data.")
Return
End Try
End If
If ResponseLengthBox.TextLength > 0 Then
If CInt(ResponseLengthBox.Text) > 0 Then
ConsoleBox.AppendText("Reading..." + vbNewLine)
Try ' Read data.
stm.Read(rBuf, 0, rBuf.Length)
Catch ex As Exception
MessageBox.Show("Could not read response.")
End Try
ConsoleBox.AppendText(Encoding.ASCII.GetString(rBuf))
ConsoleBox.AppendText(vbNewLine)
End If
End If
Else
MessageBox.Show("Client is not connected yet.")
End If
End Sub
End Class
Last edited by wolf99; Jul 19th, 2013 at 01:48 PM.
Thanks
-
Jul 19th, 2013, 03:23 PM
#2
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!
-
Jul 19th, 2013, 03:58 PM
#3
Thread Starter
Hyperactive Member
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
-
Jul 19th, 2013, 04:08 PM
#4
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.
-
Jul 19th, 2013, 04:16 PM
#5
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!
-
Jul 19th, 2013, 04:35 PM
#6
Re: NetworkStream.Read() only ever reads first five bytes?
Originally Posted by dunfiddlin
(Don't tell him I said that, It'll go straight to his head! )
Too late
-
Jul 20th, 2013, 06:06 AM
#7
Thread Starter
Hyperactive Member
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:
Do ' Loop forever - it doesnt matter about breaking out of loop at the moment
If stm.DataAvailable Then
numRead = stm.Read(rBuf, ofst, rBuf.Length)
ofst += numRead
ConsoleBox.AppendText(Encoding.ASCII.GetString(rBuf))
End If
Loop
Thanks
-
Jul 20th, 2013, 09:09 AM
#8
Thread Starter
Hyperactive Member
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
-
Jan 28th, 2018, 06:41 PM
#9
New Member
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|