Truncated data using .NET 3.5 sockets VS 2008

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Kenny D

    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(NetworkSt ream 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.BigEnd ianUnicode.GetB ytes(Msg);
    OutputStream.Wr ite(OutputBuffe r, 0, OutputBuffer.Ge tLength(0));
    OutputStream.Fl ush();
    }


    // The code that reads the socket...
    public string Read(NetworkStr eam InputStream, string EOM)
    {
    StreamReader Reader = new StreamReader(In putStream,
    Encoding.BigEnd ianUnicode);
    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.ToStr ing().EndsWith( EOM))
    {
    string ErrorMessage = string.Format(" Error: Incomplete
    Message\r\n\r\n {0}\r\n[PREMATURE END OF MESSAGE]",
    MsgText.ToStrin g());

    MOSNetTraceSour ce.TraceData(Tr aceEventType.Er ror,
    ErrorMessage);
    LogWriter.Write Error(ErrorMess age);
    }

    return (null);
    }

    InChar = Reader.Read();

    MsgText.Append( (char)InChar);

    if (MsgText.Length 10 && (char)InChar == '\n')
    {
    if (MsgText.ToStri ng().EndsWith(E OM))
    {
    break;
    }
    }

    return(MsgText. ToString());
    }
  • Kenny D

    #2
    Re: Truncated data using .NET 3.5 sockets VS 2008

    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.

    Comment

    • Kenny D

      #3
      Re: Truncated data using .NET 3.5 sockets VS 2008

      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.Rea d(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.

      Comment

      • Kenny D

        #4
        Re: Truncated data using .NET 3.5 sockets VS 2008

        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.Rea d(Buffer, 0, ReadBufferSize) ;

        if (BytesRead 0)
        {
        MsgText.Append( Encoding.BigEnd ianUnicode.GetS tring(Buffer));
        }

        string Text = MsgText.ToStrin g();
        Int32 Pos = Text.IndexOf(EO M);

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

        break;
        }

        } while (InputStream.Da taAvailable);

        Comment

        • Kenny D

          #5
          Re: Truncated data using .NET 3.5 sockets VS 2008

          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.

          Comment

          • Peter Duniho

            #6
            Re: Truncated data using .NET 3.5 sockets VS 2008

            On Mon, 24 Mar 2008 12:45:58 -0700, Kenny D <kennydevries@h otmail.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.Rea d(Buffer, 0, ReadBufferSize) ;
            >
            if (BytesRead 0)
            {
            MsgText.Append( Encoding.BigEnd ianUnicode.GetS tring(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.ToStrin g();
            Int32 Pos = Text.IndexOf(EO M);
            >
            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.Da taAvailable);
            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

            Comment

            Working...