1

I am trying to send a value by socket .So i have two parts in my project Client and server .

The client sends a value to server using this code :

  NetworkStream networkStream = socketForServer.GetStream();
            System.IO.BinaryWriter binaryWriter =
               new System.IO.BinaryWriter(networkStream);

            //------
            int messageSource = 0;
            int messageDesitination = 0;
            int interlockingId = 0;
            int trackId = 0;
            int trainId = 2;
            int direction = 0;
            int messageType = 0;
            int informationType = 0;
            int dateTime = 0;

foreach (Sensor LeftSensorList in LeftSensor)
                {

                    binaryWriter.Write(messageSource);
                    binaryWriter.Write(messageDesitination);
                    binaryWriter.Write(interlockingId);
                    binaryWriter.Write(trackId);
                    binaryWriter.Write(trainId);
                    binaryWriter.Write(direction);
                    binaryWriter.Write(messageType);
                    binaryWriter.Write(informationType);
                    binaryWriter.Write(dateTime);

                    binaryWriter.Flush();
                    binaryWriter.Close();
                    Thread.Sleep(4000);

                }

In server part i should read the binary values :

static void Listeners()
        {

            Socket socketForClient = tcpListener.AcceptSocket();
            if (socketForClient.Connected)
            {

                NetworkStream networkStream = new NetworkStream(socketForClient);

                while (true)
                {                                
                    List<int> variables = new List<int>();
                    using (var reader = new BinaryReader(networkStream))
                    {

                        int messageSource = reader.ReadInt32();
                        int messageDesitination = reader.ReadInt32();
                        int interlockingId = reader.ReadInt32();
                        int trackId = reader.ReadInt32();
                        int trainId = reader.ReadInt32();
                        int direction = reader.ReadInt32();
                        int messageType =reader.ReadInt32();
                        int informationType = reader.ReadInt32();
                        int dateTime = reader.ReadInt32();
                         reader.Close();

                    }
            }
         }

So when the client send a value i can get the value in server part just for first time ,when a client sends another values to my server i got this error :

Stream was not readable.

Why ?

Ehsan Akbar
  • 6,977
  • 19
  • 96
  • 180

2 Answers2

5

You are closing the reader in the loop, which is closing the stream. The simplest fix is to either:

  • move the reader outside of the loop, or
  • don't use a reader at all (just talking to the stream)

However, if you need to use the reader inside the loop, you can use the new BinaryReader(Stream, Encoding, bool) constructor overload and pass true in the final parameter to tell it not to close the underlying Stream. By default, it is assumed that the reader will become responsible for the lifetime of the Stream; the leaveOpen parameter changes this behaviour.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
2

This is caused because BinaryReader assumes that it owns the stream and closes it when it uses it. If you're using 4.5 you can use this overload http://msdn.microsoft.com/en-us/library/gg712804(v=vs.110).aspx

It should look like this for you.

static void Listeners()
{

    Socket socketForClient = tcpListener.AcceptSocket();
    if (socketForClient.Connected)
    {
        NetworkStream networkStream = new NetworkStream(socketForClient);
        while (true)
        {                                
            List<int> variables = new List<int>();

            //Hint : This Line
            using (var reader = new BinaryReader(networkStream, Encoding.Default, true))
            {
                int messageSource = reader.ReadInt32();
                int messageDesitination = reader.ReadInt32();
                int interlockingId = reader.ReadInt32();
                int trackId = reader.ReadInt32();
                int trainId = reader.ReadInt32();
                int direction = reader.ReadInt32();
                int messageType =reader.ReadInt32();
                int informationType = reader.ReadInt32();
                int dateTime = reader.ReadInt32();
                reader.Close();
            }
        }   
    }
}
Aelphaeis
  • 2,593
  • 3
  • 24
  • 42
  • But i got this error now :Unable to read beyond the end of the stream.when i use using (var reader = new BinaryReader(networkStream, Encoding.Default, true)) – Ehsan Akbar Jun 27 '14 at 14:48
  • 1
    @EA I think that is a completely different problem altogether; however, this question will be able to help you I believe http://stackoverflow.com/questions/3752968/endofstream-for-binaryreader – Aelphaeis Jun 27 '14 at 14:51
  • Yes it was ,You know the size of message that i get from the client is 18 bytes ,can it help ? – Ehsan Akbar Jun 27 '14 at 14:55
  • @EA If I were you I'd put the binary reader outside of the loop. Then I'd use reader.peekchar() If it returned -1 then I'd terminate the loop. – Aelphaeis Jun 27 '14 at 14:59
  • @EA I think its more appropriate for you to ask another question. – Aelphaeis Jun 27 '14 at 15:02
  • I asked:http://stackoverflow.com/questions/24455105/unable-to-read-beyond-the-end-of-the-stream-is-caused-when-use-readbinary – Ehsan Akbar Jun 27 '14 at 15:07
  • Hi dear friend i implement the method that you suggest me,but i need some help how can i be in touch with u ? – Ehsan Akbar Jul 05 '14 at 10:05
  • Hi dear could you please take a look at this :http://stackoverflow.com/questions/24586648/send-binary-data-and-read-the-values-of-that-using-async-socket-programming – Ehsan Akbar Jul 05 '14 at 13:05