468,719 Members | 1,820 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,719 developers. It's quick & easy.

BinaryReader Not Completely Reading NetworkSocket

I have a C# application that connects to Perl application on a UNIX server.
I am able to connect and communicate both directions with the server, but
there are several occasions when it appears that the BinaryReader only reads
part of the message sent by the server.

Here is the main flow of my application.
1. Open Socket
2. Read 4 byte integer
3. Read byte array that is the size of the integer in step 2.
4. Put message in collection
5. Repeat Steps 2 through 5

Simple enough? Where my problem occurs, is that sometimes step 3 reads fewer
bytes than the integer that was read in step 2. For example, the integer in
step 2 was 3564, but the string that was parsed was only 2756 bytes long.
When we get back to the top of the loop, the integer in step 2 is
1014391148, which if you break it down byte by byte is the next 4 characters
in the string. The app crashes because it "lost it's place." I thought by
setting the socket as Blocking it would wait until it read the number of
bytes in the array (This is how I've done similar things in Java), but it
hasn't seemed to help. Also, I have tried to add Thread.Sleep(750) between
step 2 and step 3. That seems to prevent most errors from occurring, but I
am not happy with that being a solution.

Any suggestions?
Here is the way that I am declaring my socket and readers:

socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,ProtocolType.Tcp);
socket.Blocking = true;
socket.Connect(endPoint);
socket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReceiveTimeout, 0);
socket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.SendTimeout, 0);
stream = new NetworkStream(socket, FileAccess.ReadWrite, true);
reader = new BinaryReader(stream);
writer = new BinaryWriter(stream);

Here is my main loop:

while (!_stop)
{
msgLength = new byte[4];
if (reader.Read(msgLength,0,4) > 0)
{
// This stops 90% of errors, but is bad practice.
// Thread.Sleep(750);

message = new byte[length];
if (reader.Read(message,0,(int)length) > 0)
{
serverMessage = enc.GetString(message,0,(int)length);
putReceiveMessage(serverMessage);
}
}
}

Jul 21 '05 #1
2 2233
Chris P. <c@c.com> wrote:
I have a C# application that connects to Perl application on a UNIX server.
I am able to connect and communicate both directions with the server, but
there are several occasions when it appears that the BinaryReader only reads
part of the message sent by the server.

Here is the main flow of my application.
1. Open Socket
2. Read 4 byte integer
3. Read byte array that is the size of the integer in step 2.
4. Put message in collection
5. Repeat Steps 2 through 5

Simple enough? Where my problem occurs, is that sometimes step 3 reads fewer
bytes than the integer that was read in step 2. For example, the integer in
step 2 was 3564, but the string that was parsed was only 2756 bytes long.


There's no guarantee that BinaryReader.Read will read as much as you
requested. The thing to do is loop round until you've read everything
you want to.

My own BinaryReader class, available from
http://www.pobox.com/~skeet/csharp/miscutil
keeps reading until either it's reached the end of the stream or it's
read as much as you requested, but I believe the normal
BinaryReader.Read is just like Stream.Read.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #2
That was it. Thanks for your help.

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Chris P. <c@c.com> wrote:
I have a C# application that connects to Perl application on a UNIX
server.
I am able to connect and communicate both directions with the server, but
there are several occasions when it appears that the BinaryReader only
reads
part of the message sent by the server.

Here is the main flow of my application.
1. Open Socket
2. Read 4 byte integer
3. Read byte array that is the size of the integer in step 2.
4. Put message in collection
5. Repeat Steps 2 through 5

Simple enough? Where my problem occurs, is that sometimes step 3 reads
fewer
bytes than the integer that was read in step 2. For example, the integer
in
step 2 was 3564, but the string that was parsed was only 2756 bytes long.


There's no guarantee that BinaryReader.Read will read as much as you
requested. The thing to do is loop round until you've read everything
you want to.

My own BinaryReader class, available from
http://www.pobox.com/~skeet/csharp/miscutil
keeps reading until either it's reached the end of the stream or it's
read as much as you requested, but I believe the normal
BinaryReader.Read is just like Stream.Read.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Jul 21 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by gladiator | last post: by
3 posts views Thread by Kevin Trojanowski | last post: by
6 posts views Thread by Question with BinaryReader | last post: by
reply views Thread by Dave | last post: by
1 post views Thread by CARIGAR | last post: by
1 post views Thread by Oskars | last post: by
9 posts views Thread by bryonone | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.