TCP Send with Response

S

Scott

I have to send a TCP stream to a device. The device returns a response and
I cannot figure out how to catch the response. I know the device response
properly because if I connect to it using HyperTerminal I can send the
command and immediately the response is displayed back to me in
HyperTerminal. Now I need to do this programmatically. The send portion of
the code below works because the device response properly but for some
reason I'm unable to catch the response. I've looked through MANY examples
online and they all seem to look like this code block.

Please help, and thanks in advance.
Scott
([email protected])




System.Net.Sockets.TcpClient tcpClient = new System.Net.Sockets.TcpClient();

tcpClient.Connect(LED_IP, LED_Port);
System.Net.Sockets.NetworkStream networkStream =
tcpClient.GetStream();



// Does a simple write.
Byte[] sendBytes = Encoding.ASCII.GetBytes(LED_Stream);
Byte[] RecvBytes = new Byte[4096];


networkStream.Write(sendBytes, 0, sendBytes.Length);

String responseData = String.Empty;
Int32 bytes = networkStream.Read(RecvBytes,
RecvBytes.Length, 0);
responseData =
System.Text.Encoding.ASCII.GetString(RecvBytes, 0, bytes);

this.txtResult.Text = bytes.ToString() + ": " +
responseData;


networkStream.Flush();

tcpClient.NoDelay = true;
tcpClient.Close();

tcpClient = null;
networkStream = null;
 
S

Scott

Ok I've already found a portion of my problem. I had 2 parameters switched
on the Read command.

Wrong:
Int32 bytes = networkStream.Read(RecvBytes, RecvBytes.Length, 0);

Correct:
Int32 bytes = networkStream.Read(RecvBytes, 0, RecvBytes.Length);


Now my last problem is that I'm getting a few bytes of data back but not all
of it. Like it's happening too fast. I'm getting 3-5 bytes when I should
be getting about 20.

Any Ideas?
 
S

Scott

wow... I've fought this for 3 days.... today must be a good day because I
have it working now.

I just put the thread to sleep for 100 ms and it all works as expected.
 
P

Peter Duniho

Scott said:
wow... I've fought this for 3 days.... today must be a good day because
I have it working now.

I just put the thread to sleep for 100 ms and it all works as expected.

It may work, but you didn't fix it correctly. And as a general rule,
using Thread.Sleep() or similar is never the correct way to fix network
i/o problems.

The most obvious problem in your code is that you are only calling
Read() once. TCP provides no guarantees at all about how many bytes a
given call to Read() will return. In only guarantees that bytes you
receive will be received in the same order in which they were sent.

You must call Read() repeatedly until you've received as much data as is
required.

Pete
 
O

ozbear

It may work, but you didn't fix it correctly. And as a general rule,
using Thread.Sleep() or similar is never the correct way to fix network
i/o problems.

The most obvious problem in your code is that you are only calling
Read() once. TCP provides no guarantees at all about how many bytes a
given call to Read() will return. In only guarantees that bytes you
receive will be received in the same order in which they were sent.

You must call Read() repeatedly until you've received as much data as is
required.

Pete

It provides a couple more guarantees than that.
It also guarantees that the data will not be duplicated, nor lost
without an error. This is supplementary to, but not the same as
receiving data in the same order as sent.

Also, when Read returns and there was no error and
the sender has not closed the stream, the read count must be >= 1.

Oz
 
M

Mike Schilling

Peter said:
It may work, but you didn't fix it correctly. And as a general
rule,
using Thread.Sleep() or similar is never the correct way to fix
network i/o problems.

The most obvious problem in your code is that you are only calling
Read() once. TCP provides no guarantees at all about how many bytes
a
given call to Read() will return. In only guarantees that bytes you
receive will be received in the same order in which they were sent.

You must call Read() repeatedly until you've received as much data
as
is required.

Or you've seen the terminating character, or no data has been sent for
N milliseconds, or whatever, for your particular application, means
"end of transmission". (In the old days, using DecNET instead of
TCP, I could issue a "read record" request, and the receiver would
read exactly as much data as the sender sent. Nowadays, the concept
of record has pretty much gone away, everything's just a byte stream,
and every networking application gets to create its own communications
protocol. It's so much simpler. Not.)
 
P

Peter Duniho

Mike said:
[...]
You must call Read() repeatedly until you've received as much data
as is required.

Or you've seen the terminating character, or no data has been sent for
N milliseconds, or whatever, for your particular application, means
"end of transmission".

IMHO, those ALL fall under the description "as much data as is
required". :)

(In the old days, using DecNET instead of
TCP, I could issue a "read record" request, and the receiver would
read exactly as much data as the sender sent. Nowadays, the concept
of record has pretty much gone away, everything's just a byte stream,
and every networking application gets to create its own communications
protocol. It's so much simpler. Not.)

Only the prevalence of TCP/IP makes it seem like it's that way. There
are lots of other protocols to choose from, if you don't need to go over
the Internet, and many of them support connection-oriented, reliable,
message-based communications.

Pete
 
A

Arne Vajhøj

Or you've seen the terminating character, or no data has been sent for
N milliseconds, or whatever, for your particular application, means
"end of transmission". (In the old days, using DecNET instead of
TCP, I could issue a "read record" request, and the receiver would
read exactly as much data as the sender sent. Nowadays, the concept
of record has pretty much gone away, everything's just a byte stream,
and every networking application gets to create its own communications
protocol. It's so much simpler. Not.)

RMS over DECNet is record oriented.

And even $QIO(W) with DECnet pass length.

Arne
 
M

Mike Schilling

Arne said:
RMS over DECNet is record oriented.

And even $QIO(W) with DECnet pass length.

Sure, my point is that I haven't used DECnet for decades; it's all TCP
these days.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top