IOException thrown by BinaryFormatter.Deserialize

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

    IOException thrown by BinaryFormatter.Deserialize

    Hi,

    When I'm doing BinaryFormatter .Deserialize() over a TCP socket. When I'm
    closing the TcpListener by invoking the TcpListener.Sto p(); I get:

    System.IO.IOExc eption with message "Unable to read data from the transport
    connection." that InnerException of type System.Net.Sock ets.SocketExcep tion
    saying "An established connection was aborted by the software in your host
    machine".

    The code I'm using is (it's not the complete code because the complete code
    is very long and threaded):
    -------------------------------------------------------------
    string serverIP = "some IP address";
    int port = 3001;

    TcpListener m_server;
    m_server = new TcpListener( System.Net.IPAd dress.Parse(ser verIP), port );

    Socket m_socket = m_server.Accept Socket();

    System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er formatter =
    new System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er();

    while( true )
    {
    NetworkStream networkStream = new NetworkStream(m _socket);
    MyObjectType obj = formatter.Deser ialize(networkS tream) as MyObjectType;
    // throw the IOException when the TcpListener is closed by TcpListener.Sto p();
    }
    -------------------------------------------------------------

    Can anybody tell me how to avoid this exception?


    ---------
    Thanks
    Sharon
  • Ignacio Machin \( .NET/ C# MVP \)

    #2
    Re: IOException thrown by BinaryFormatter .Deserialize

    Hi,

    Must probably it's cause the networkstream ends without further notice (
    probably cause the client sent all the data and closed the connection ) .

    Try to do this, copy the networkstream to a memorystream, later deserialize
    from that memory stream.

    Do you by any chance send the size first?


    cheers,

    --
    Ignacio Machin,
    ignacio.machin AT dot.state.fl.us
    Florida Department Of Transportation



    "Sharon" <Sharon@discuss ions.microsoft. com> wrote in message
    news:14EF7D65-E2A4-4213-9731-324221AC8EA0@mi crosoft.com...[color=blue]
    > Hi,
    >
    > When I'm doing BinaryFormatter .Deserialize() over a TCP socket. When I'm
    > closing the TcpListener by invoking the TcpListener.Sto p(); I get:
    >
    > System.IO.IOExc eption with message "Unable to read data from the
    > transport
    > connection." that InnerException of type
    > System.Net.Sock ets.SocketExcep tion
    > saying "An established connection was aborted by the software in your host
    > machine".
    >
    > The code I'm using is (it's not the complete code because the complete
    > code
    > is very long and threaded):
    > -------------------------------------------------------------
    > string serverIP = "some IP address";
    > int port = 3001;
    >
    > TcpListener m_server;
    > m_server = new TcpListener( System.Net.IPAd dress.Parse(ser verIP), port );
    >
    > Socket m_socket = m_server.Accept Socket();
    >
    > System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er formatter =
    > new System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er();
    >
    > while( true )
    > {
    > NetworkStream networkStream = new NetworkStream(m _socket);
    > MyObjectType obj = formatter.Deser ialize(networkS tream) as
    > MyObjectType;
    > // throw the IOException when the TcpListener is closed by
    > TcpListener.Sto p();
    > }
    > -------------------------------------------------------------
    >
    > Can anybody tell me how to avoid this exception?
    >
    >
    > ---------
    > Thanks
    > Sharon[/color]


    Comment

    • Sharon

      #3
      Re: IOException thrown by BinaryFormatter .Deserialize

      Thanks Ignacio,

      The client (the side that does the Serialize) is not closing the socket.
      The IOException is thrown when I'm doing the stop on the server side (the
      side that does the Deserialize).

      The while loop is already Deserialized 30 MyObjectType objects, and this all
      the objects that has been Serialized to the socket on the other side.

      Can you post a sample code explaining what you want me to check?

      No, I'm not sending any size first, I simply doing this:

      string serverIP = "The server IP";
      int port = 3001;
      Socket m_socket = new Socket(AddressF amily.InterNetw ork, SocketType.Stre am,
      ProtocolType.Tc p);
      System.Net.IPEn dPoint ep = new
      System.Net.IPEn dPoint(System.N et.IPAddress.Pa rse(serverIP ), port);
      System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er formatter =
      new System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er();
      NetworkStream networkStream = new NetworkStream(m _socket);
      foreach( MyObjectType obj in myObjectTypeLis t )
      {
      formatter.Seria lize(networkStr eam, obj);
      }
      // waiting...


      Any idea?

      -----
      Thanks
      Sharon

      Comment

      • Ignacio Machin \( .NET/ C# MVP \)

        #4
        Re: IOException thrown by BinaryFormatter .Deserialize

        Hi,

        I had a similar situation, the problem it seems that the client send the
        data and just close the connection, sometimes even without sending all the
        data, ( there is a property of TcpClient.Linge rState that control this) and
        the server side was reporting the same error you are seeing.

        Do this test, use a memorystream to read the data , use
        NetworkStream.D ataAvailable , see the example in the help, or you could just
        read a byte at a time:

        MemoryStream mem = new MemoryStream()
        int b=-1;
        while( (b=networkstrea m.ReadByte()) != -1 )
        mem.WriteByte( (byte)b);


        cheers,

        --
        Ignacio Machin,
        ignacio.machin AT dot.state.fl.us
        Florida Department Of Transportation



        "Sharon" <Sharon@discuss ions.microsoft. com> wrote in message
        news:3B6E8F2E-66D6-464A-AB56-3946CA574289@mi crosoft.com...[color=blue]
        > Thanks Ignacio,
        >
        > The client (the side that does the Serialize) is not closing the socket.
        > The IOException is thrown when I'm doing the stop on the server side (the
        > side that does the Deserialize).
        >
        > The while loop is already Deserialized 30 MyObjectType objects, and this
        > all
        > the objects that has been Serialized to the socket on the other side.
        >
        > Can you post a sample code explaining what you want me to check?
        >
        > No, I'm not sending any size first, I simply doing this:
        >
        > string serverIP = "The server IP";
        > int port = 3001;
        > Socket m_socket = new Socket(AddressF amily.InterNetw ork,
        > SocketType.Stre am,
        > ProtocolType.Tc p);
        > System.Net.IPEn dPoint ep = new
        > System.Net.IPEn dPoint(System.N et.IPAddress.Pa rse(serverIP ), port);
        > System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er formatter =
        > new System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er();
        > NetworkStream networkStream = new NetworkStream(m _socket);
        > foreach( MyObjectType obj in myObjectTypeLis t )
        > {
        > formatter.Seria lize(networkStr eam, obj);
        > }
        > // waiting...
        >
        >
        > Any idea?
        >
        > -----
        > Thanks
        > Sharon[/color]


        Comment

        • Ignacio Machin \( .NET/ C# MVP \)

          #5
          Re: IOException thrown by BinaryFormatter .Deserialize

          Hi,

          An extra question, you said that it already had 30 objects deserialized ,
          how many are you sending? 31?


          cheers,

          --
          Ignacio Machin,
          ignacio.machin AT dot.state.fl.us
          Florida Department Of Transportation



          "Sharon" <Sharon@discuss ions.microsoft. com> wrote in message
          news:3B6E8F2E-66D6-464A-AB56-3946CA574289@mi crosoft.com...[color=blue]
          > Thanks Ignacio,
          >
          > The client (the side that does the Serialize) is not closing the socket.
          > The IOException is thrown when I'm doing the stop on the server side (the
          > side that does the Deserialize).
          >
          > The while loop is already Deserialized 30 MyObjectType objects, and this
          > all
          > the objects that has been Serialized to the socket on the other side.
          >
          > Can you post a sample code explaining what you want me to check?
          >
          > No, I'm not sending any size first, I simply doing this:
          >
          > string serverIP = "The server IP";
          > int port = 3001;
          > Socket m_socket = new Socket(AddressF amily.InterNetw ork,
          > SocketType.Stre am,
          > ProtocolType.Tc p);
          > System.Net.IPEn dPoint ep = new
          > System.Net.IPEn dPoint(System.N et.IPAddress.Pa rse(serverIP ), port);
          > System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er formatter =
          > new System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er();
          > NetworkStream networkStream = new NetworkStream(m _socket);
          > foreach( MyObjectType obj in myObjectTypeLis t )
          > {
          > formatter.Seria lize(networkStr eam, obj);
          > }
          > // waiting...
          >
          >
          > Any idea?
          >
          > -----
          > Thanks
          > Sharon[/color]


          Comment

          • Sharon

            #6
            Re: IOException thrown by BinaryFormatter .Deserialize

            Hi Ignacio,

            That's exactly the point, I'm Serialize 30 objects and getting them all at
            the deserializing side.
            So all the data was sent successfully.
            But still I get this exception when closing the TcpListener.

            What do you think.

            --------
            Thanks
            Sharon

            Comment

            • Ignacio Machin \( .NET/ C# MVP \)

              #7
              Re: IOException thrown by BinaryFormatter .Deserialize

              Hi Sharon,

              I have a similar problem

              DO this, Check the InnerException to see what it contains, if so what is
              the ErrorCode you are getting?

              cheers,

              --
              Ignacio Machin,
              ignacio.machin AT dot.state.fl.us
              Florida Department Of Transportation



              "Sharon" <Sharon@discuss ions.microsoft. com> wrote in message
              news:0D635B48-720D-4493-A065-A64F878A0F04@mi crosoft.com...[color=blue]
              > Hi Ignacio,
              >
              > That's exactly the point, I'm Serialize 30 objects and getting them all at
              > the deserializing side.
              > So all the data was sent successfully.
              > But still I get this exception when closing the TcpListener.
              >
              > What do you think.
              >
              > --------
              > Thanks
              > Sharon[/color]


              Comment

              • Sharon

                #8
                Re: IOException thrown by BinaryFormatter .Deserialize

                Hi Ignacio,

                Ok,
                The top exception is System.IO.IOExc eption {"Unable to read data from the
                transport connection."}, and it contains an inner exception
                System.Net.Sock ets.SocketExcep tion {"An established connection was aborted by
                the software in your host machine"}

                NativeErrorCode = 10053

                Stack trace:

                System.Net.Sock ets.NetworkStre am.Read(Byte[] buffer, Int32 offset, Int32 size)
                System.IO.Strea m.ReadByte()
                at System.IO.Binar yReader.FillBuf fer(Int32 numBytes)
                System.IO.Binar yReader.ReadByt e()
                System.Runtime. Serialization.F ormatters.Binar y.__BinaryParse r.ReadByte(
                System.Runtime. Serialization.F ormatters.Binar y.Serialization HeaderRecord.Re ad(__BinaryPars er input
                System.Runtime. Serialization.F ormatters.Binar y.__BinaryParse r.ReadSerializa tionHeaderRecor d()
                System.Runtime. Serialization.F ormatters.Binar y.__BinaryParse r.Run()
                System.Runtime. Serialization.F ormatters.Binar y.ObjectReader. Deserialize(Hea derHandler
                handler, __BinaryParser serParser, Boolean fCheck, IMethodCallMess age
                methodCallMessa ge)
                System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er.Deserialize( Stream
                serializationSt ream, HeaderHandler handler, Boolean fCheck,
                IMethodCallMess age methodCallMessa ge
                System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er.Deserialize( Stream serializationSt ream, HeaderHandler handler
                System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er.Deserialize( Stream serializationSt ream)


                I hope it gives you what you need.


                ---------------
                Thanks again
                Sharon

                Comment

                • Steven Cheng

                  #9
                  Re: IOException thrown by BinaryFormatter .Deserialize


                  Hi Sharon,

                  Seems there are something else cause the formatter to read further data from
                  the NetworkStream after you've close the Tcp connection. Have you tried using
                  NetworkStream.c lose() method to close both the stream and the underlying Tcp
                  connection? Also, I think Ignacio's suggestion on using a memory stream to
                  temporarly hold the binary data is also a considerable means for testing.

                  Please feel free to post here if you got any further finding.

                  Thanks,

                  Steven Cheng

                  "Sharon" wrote:
                  [color=blue]
                  > Hi Ignacio,
                  >
                  > Ok,
                  > The top exception is System.IO.IOExc eption {"Unable to read data from the
                  > transport connection."}, and it contains an inner exception
                  > System.Net.Sock ets.SocketExcep tion {"An established connection was aborted by
                  > the software in your host machine"}
                  >
                  > NativeErrorCode = 10053
                  >
                  > Stack trace:
                  >
                  > System.Net.Sock ets.NetworkStre am.Read(Byte[] buffer, Int32 offset, Int32 size)
                  > System.IO.Strea m.ReadByte()
                  > at System.IO.Binar yReader.FillBuf fer(Int32 numBytes)
                  > System.IO.Binar yReader.ReadByt e()
                  > System.Runtime. Serialization.F ormatters.Binar y.__BinaryParse r.ReadByte()
                  > System.Runtime. Serialization.F ormatters.Binar y.Serialization HeaderRecord.Re ad(__BinaryPars er input)
                  > System.Runtime. Serialization.F ormatters.Binar y.__BinaryParse r.ReadSerializa tionHeaderRecor d()
                  > System.Runtime. Serialization.F ormatters.Binar y.__BinaryParse r.Run()
                  > System.Runtime. Serialization.F ormatters.Binar y.ObjectReader. Deserialize(Hea derHandler
                  > handler, __BinaryParser serParser, Boolean fCheck, IMethodCallMess age
                  > methodCallMessa ge)
                  > System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er.Deserialize( Stream
                  > serializationSt ream, HeaderHandler handler, Boolean fCheck,
                  > IMethodCallMess age methodCallMessa ge)
                  > System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er.Deserialize( Stream serializationSt ream, HeaderHandler handler)
                  > System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er.Deserialize( Stream serializationSt ream)
                  >
                  >
                  > I hope it gives you what you need.
                  >
                  >
                  > ---------------
                  > Thanks again
                  > Sharon[/color]

                  Comment

                  • Steven Cheng

                    #10
                    Re: IOException thrown by BinaryFormatter .Deserialize


                    Hi Sharon,

                    Seems there are something else cause the formatter to read further data from
                    the NetworkStream after you've close the Tcp connection. Have you tried using
                    NetworkStream.c lose() method to close both the stream and the underlying Tcp
                    connection? Also, I think Ignacio's suggestion on using a memory stream to
                    temporarly hold the binary data is also a considerable means for testing.

                    Please feel free to post here if you got any further finding.

                    Thanks,

                    Steven Cheng

                    "Sharon" wrote:
                    [color=blue]
                    > Hi Ignacio,
                    >
                    > Ok,
                    > The top exception is System.IO.IOExc eption {"Unable to read data from the
                    > transport connection."}, and it contains an inner exception
                    > System.Net.Sock ets.SocketExcep tion {"An established connection was aborted by
                    > the software in your host machine"}
                    >
                    > NativeErrorCode = 10053
                    >
                    > Stack trace:
                    >
                    > System.Net.Sock ets.NetworkStre am.Read(Byte[] buffer, Int32 offset, Int32 size)
                    > System.IO.Strea m.ReadByte()
                    > at System.IO.Binar yReader.FillBuf fer(Int32 numBytes)
                    > System.IO.Binar yReader.ReadByt e()
                    > System.Runtime. Serialization.F ormatters.Binar y.__BinaryParse r.ReadByte()
                    > System.Runtime. Serialization.F ormatters.Binar y.Serialization HeaderRecord.Re ad(__BinaryPars er input)
                    > System.Runtime. Serialization.F ormatters.Binar y.__BinaryParse r.ReadSerializa tionHeaderRecor d()
                    > System.Runtime. Serialization.F ormatters.Binar y.__BinaryParse r.Run()
                    > System.Runtime. Serialization.F ormatters.Binar y.ObjectReader. Deserialize(Hea derHandler
                    > handler, __BinaryParser serParser, Boolean fCheck, IMethodCallMess age
                    > methodCallMessa ge)
                    > System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er.Deserialize( Stream
                    > serializationSt ream, HeaderHandler handler, Boolean fCheck,
                    > IMethodCallMess age methodCallMessa ge)
                    > System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er.Deserialize( Stream serializationSt ream, HeaderHandler handler)
                    > System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er.Deserialize( Stream serializationSt ream)
                    >
                    >
                    > I hope it gives you what you need.
                    >
                    >
                    > ---------------
                    > Thanks again
                    > Sharon[/color]

                    Comment

                    • Sharon

                      #11
                      Re: IOException thrown by BinaryFormatter .Deserialize

                      Hi Steven,

                      When I'm closing I'm first doing:
                      TcpListener.Sto p();

                      And then:
                      Socket.Close();

                      And when I’m catching the IOException (thrown by the
                      formatter.Deser ialize(networkS tream)) I’m doing on a finally block:
                      NetworkStream.C lose();


                      Should I do it differently?


                      --------
                      Thanks
                      Sharon

                      Comment

                      • Sharon

                        #12
                        Re: IOException thrown by BinaryFormatter .Deserialize

                        Hi Steven,

                        When I'm closing I'm first doing:
                        TcpListener.Sto p();

                        And then:
                        Socket.Close();

                        And when I’m catching the IOException (thrown by the
                        formatter.Deser ialize(networkS tream)) I’m doing on a finally block:
                        NetworkStream.C lose();


                        Should I do it differently?


                        --------
                        Thanks
                        Sharon

                        Comment

                        • Peter Huang [MSFT]

                          #13
                          Re: IOException thrown by BinaryFormatter .Deserialize

                          Hi

                          Here is a KB may related with your problem.

                          PRB: TcpClient Close Method Does Not Close the Underlying TCP Connection
                          Microsoft Support is here to help you with Microsoft products. Find how-to articles, videos, and training for Microsoft Copilot, Microsoft 365, Windows 11, Surface, and more.



                          Also I suggest you try to use the syntax something like below to receive
                          the network stream.


                          [pseudocode]
                          try
                          {
                          Int32 port = 13000;
                          TcpListener server = new TcpListener(por t);
                          server.Start();
                          Byte[] bytes = new Byte[256];
                          while(true)
                          {
                          Console.Write(" Waiting for a connection... ");
                          TcpClient client = server.AcceptTc pClient();
                          Console.WriteLi ne("Connected!" );
                          data = null;
                          NetworkStream stream = client.GetStrea m();
                          Int32 i;
                          int pos=0;
                          MemoryStream ms = new MemoryStream();
                          while((i = stream.Read(byt es, 0, bytes.Length))! =0)
                          {
                          ms.Write(bytes, pos,i);
                          pos +=i;
                          }
                          stream.Close();
                          client.Close();
                          }
                          }
                          catch(SocketExc eption e)
                          {
                          Console.WriteLi ne("SocketExcep tion: {0}", e);
                          }
                          //Handle the Deserial here.
                          Console.WriteLi ne("\nHit enter to continue...");
                          Console.Read();
                          //Close the listener.
                          tcpListener.Sto p();
                          }


                          Best regards,

                          Peter Huang
                          Microsoft Online Partner Support

                          Get Secure! - www.microsoft.com/security
                          This posting is provided "AS IS" with no warranties, and confers no rights.

                          Comment

                          • Sharon

                            #14
                            Re: IOException thrown by BinaryFormatter .Deserialize

                            Hi Peter,

                            Thanks for your reply.

                            From your replay I have 2 questions:
                            (1) The transportation speed is most important to me, so I thought using the
                            TcpListener.Acc eptSocket() will be best.
                            Why should I use the TcpListener.Acc eptTcpClient() instead the
                            AcceptSocket()? Is it better or preferred?

                            (2) In the code you have posted; the:
                            MemoryStream ms = new MemoryStream();
                            while((i = stream.Read(byt es, 0, bytes.Length))! =0)
                            {
                            ms.Write(bytes, pos,i);
                            pos +=i;
                            }

                            For what is it good for?
                            Why are you using the MemoryStream?
                            As I posted, I’m using the BinaryFormatter .Deserialize(ne tworkStream). How
                            should I use it now in reference to your suggested code?


                            --------
                            Thanks
                            Sharon

                            Comment

                            • Sharon

                              #15
                              Re: IOException thrown by BinaryFormatter .Deserialize

                              Hi again Peter,

                              I have changed my code as you suggested to something like that
                              ///////////////////////////////////////////////////////////////////////////////
                              TcpListener tcpListener = new TcpListener(
                              System.Net.IPAd dress.Parse(ser verIP), port );
                              TcpClient tcpClient = tcpListener.Acc eptTcpClient();

                              System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er formatter =
                              new System.Runtime. Serialization.F ormatters.Binar y.BinaryFormatt er();
                              NetworkStream networkStream = m_tcpClient.Get Stream();

                              myClassType myClass = null;
                              int count = 30;
                              while( count != 0 )
                              {
                              myClass = formatter.Deser ialize(networkS tream) as myClassType;
                              ++count;
                              }

                              tcpListener.Sto p();
                              networkStream.C lose();
                              tcpClient.Close ()
                              ///////////////////////////////////////////////////////////////////////////////

                              But now when the tcpListener.Sto p() is invoked, the formatter.Deser ialize()
                              throws
                              SerializationEx ception{"End of Stream encountered before parsing was
                              completed."}
                              But all the myClass objects that are sent are received successfully.

                              I’m not if this error is better then the IOException I had before.

                              What do you think?


                              --------
                              Thanks
                              Sharon

                              Comment

                              Working...