469,623 Members | 1,497 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

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

Truncated data using .NET 3.5 sockets VS 2008

I am having trouble sending streams of data from one socket to another
using the following code.

When the transmitter is running on the same machine as the receiver,
the data transmits perfectly. When the transmitter runs on another
machine, the data gets truncated at semi random places.

The data being transmitted is a unicode XML string. There is nothing
special about it other than being unicode.

The message stream is terminated with "</mos>\r\n". I read the stream
1 byte at a time in the code below. I have tried various other "block
read" methods with the same results.

This used to work when I was using .Net 2.0 under VS 2005. Since
upgrading to VS 2008, this no longer works correctly.

Is there anything I am doing wrong based on the code below or is there
something I have overlooked vis-a-vis VS 2008? Is there something
wrong with my network set up that would cause this - a service pack
release or something? I have tested this with the Windows Firewall on
and off - makes no difference.

Any help appreciated.

// The code that writes to the socket...
public void Write(NetworkStream OutputStream, string Msg)
{
Msg += "\r\n";
while (Msg.Contains("\r\n\r\n"))
Msg = Msg.Replace("\r\n\r\n", "\r\n");

byte[] OutputBuffer = Encoding.BigEndianUnicode.GetBytes(Msg);
OutputStream.Write(OutputBuffer, 0, OutputBuffer.GetLength(0));
OutputStream.Flush();
}
// The code that reads the socket...
public string Read(NetworkStream InputStream, string EOM)
{
StreamReader Reader = new StreamReader(InputStream,
Encoding.BigEndianUnicode);
StringBuilder MsgText = new StringBuilder();

Int32 InChar = -1;

while (true)
{

// If the next character == -1, we have been cut off and
disconnected or there was an error
// in the message being sent to the reader. Either way, stop
reading.
if ((InChar = Reader.Peek()) == -1)
{

if (!MsgText.ToString().EndsWith(EOM))
{
string ErrorMessage = string.Format("Error: Incomplete
Message\r\n\r\n{0}\r\n[PREMATURE END OF MESSAGE]",
MsgText.ToString());

MOSNetTraceSource.TraceData(TraceEventType.Error,
ErrorMessage);
LogWriter.WriteError(ErrorMessage);
}

return (null);
}

InChar = Reader.Read();

MsgText.Append((char)InChar);

if (MsgText.Length 10 && (char)InChar == '\n')
{
if (MsgText.ToString().EndsWith(EOM))
{
break;
}
}

return(MsgText.ToString());
}
Mar 24 '08 #1
5 2293
Thanks, Jon.

I will check out the utility you mentioned.

I know that one character at a time is inefficient, it's just happened
to be the way I did it when I decided to seek help here. Not shown in
the code is the blcok-read method which results in the same errors.

I am pulling what's left of my hair out over this. All this stuff
worked fine a couple of weeks ago.
Mar 24 '08 #2
Read(), as I have used it in the original example is a blocking call.
Peek is a blocking call as well.

I am no network expert and this code worked like a charm before I
upgraded to VS2008 and .NET 3.5. I am not emphatically stating that
they are the culprits but the coincidence is questionable at least.

The problem with using the...
BytesRead = InputStream.Read(Buffer, 0, ReadBufferSize);
.... method is that the results are the same - truncated data.

Additionally, I used WireShark (WS) and it indicates a bad CRC on some
of the packets. The interesting thing is that it looks like the data
is getting to the target machine ok. I can look at the data in
WireShark and see all the proper tags in the XML, including the
message end tag. I don't see any strange data embedded in the XML in
WS.

Any other ideas? All help appreciated.

Thanks, so far.
Mar 24 '08 #3
Blocking Peek(): I can place a break point after the call to peek.
The break point never gets hit until data is in the pipe waiting to be
read.

I will code up the console applications. They won't be ready for a
couple of hours as I have to step out. This will help out a lot
because I have not had anyone else try this on their machines.

Please keep an eye on this thread. I really need to get to the bottom
of this.

Thanks,

K

Code for the other method...

Int32 BytesRead = 0;
do
{
byte[] Buffer = new byte[ReadBufferSize];
BytesRead = InputStream.Read(Buffer, 0, ReadBufferSize);

if (BytesRead 0)
{
MsgText.Append(Encoding.BigEndianUnicode.GetString (Buffer));
}

string Text = MsgText.ToString();
Int32 Pos = Text.IndexOf(EOM);

if (Pos 0)
{
Pos += EOM.Length;
MsgText.Length = Pos;

break;
}

} while (InputStream.DataAvailable);
Mar 24 '08 #4
Also, the other code snippet was thrown together hastily just to test
for the truncation. It has not been thoroughly tested. Neither is it
very elegant.
Mar 24 '08 #5
On Mon, 24 Mar 2008 12:45:58 -0700, Kenny D <ke**********@hotmail.com
wrote:
Blocking Peek(): I can place a break point after the call to peek.
The break point never gets hit until data is in the pipe waiting to be
read.
The next statement after the call to Peek() only executes when Peek()
returns something other than -1. Are you sure that it's not just that
Peek() keeps returning -1?

And I reiterate: given that the docs say that Peek() will return -1 if no
data is available, under what condition would Peek() block? Conversely,
feel free to describe a condition under which Peek() would return -1.
I will code up the console applications. They won't be ready for a
couple of hours as I have to step out. This will help out a lot
because I have not had anyone else try this on their machines.

Please keep an eye on this thread. I really need to get to the bottom
of this.
For better or worse, your question is likely to get exactly the same
attention anyone else's does. If you have an urgent situation, you may
want to consider paid developer support from Microsoft. You'll find that
many of us are reasonably responsive, but there's not likely to be any
point in expressing your urgency. And at worst, it implies that we are
are your beck and call, which is surely not the implication you intended..
Thanks,
You're welcome. :)
K

Code for the other method...
I see at least four problems in that code, at least three of which I
believe are significant.

Specifically:
>
Int32 BytesRead = 0;
do
{
byte[] Buffer = new byte[ReadBufferSize];
BytesRead = InputStream.Read(Buffer, 0, ReadBufferSize);

if (BytesRead 0)
{
MsgText.Append(Encoding.BigEndianUnicode.GetString (Buffer));
}
At the very least, you have a problem any time that a Unicode character
gets split in two during network transmission. You also aren't taking
into account the actual count of BytesRead when you convert the buffer to
a string, but since the buffer is zero-filled and you allocate it anew
each time (inefficient, but workable) I think this isn't as likely to
cause a problem.
>
string Text = MsgText.ToString();
Int32 Pos = Text.IndexOf(EOM);

if (Pos 0)
{
Pos += EOM.Length;
MsgText.Length = Pos;

break;
}
What happens when you receive more than one message in a single read?
You're just discarding whatever text was read after the current message's
EOM.
>
} while (InputStream.DataAvailable);
Like Peek(), the DataAvailable property doesn't tell you anything about
the future condition of the stream. So if you stop here, then as soon as
the stream gets temporarily interrupted you incorrectly will detect that
as the end of the message. Of course, if the actual EOM text hasn't
arrived yet, your code breaks.

Pete
Mar 24 '08 #6

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by z. f. | last post: by
2 posts views Thread by bil.shah | last post: by
reply views Thread by David A. Schramm | last post: by
4 posts views Thread by R.Manikandan | last post: by
10 posts views Thread by John Salerno | last post: by
reply views Thread by Jean-Paul Calderone | last post: by
25 posts views Thread by 4.4.bsd | last post: by
reply views Thread by gheharukoh7 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.