NetworkStream.Read doesn't work the first time called

I have a simple tcp/ip chat program with a server and client. The first time I send a packet, it makes it to the client but during the NetworkStream.Read it stops execution and doesn't throw an exception. The next packet I send is read and processed perfectly. Another weird thing I noticed is that MyNetworkStream.DataAvailable is always false even if I get information from the server so I have to put a debug symbol and skip over it. I wish I could post all my code but it is long so I will post where I read and write to the network stream.

 public void Listen(int byteLength)
        {
            var buffer = new byte[byteLength];
            MySocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(Read), buffer);
        }

        private  void Read(IAsyncResult ar)
        {
            while (MySocket.Connected)
            {
            MyNetworkStream = new NetworkStream(MySocket);
            var buffer = new byte[((byte[])ar.AsyncState).Length];
            if (!MyNetworkStream.DataAvailable)
                throw new Exception("Data not available");
                MyNetworkStream.Read(buffer, 0, buffer.Length); <------Here it stops execution without throwing an exception
                string content = Encoding.ASCII.GetString(buffer);
                if(OnRead == null)
                    continue;
                var e = new CommandEventArgs( null, content);
                Control target = null;
                if (OnRead.Target is Control)
                    target = (Control)OnRead.Target;
                if (target != null && target.InvokeRequired)
                    target.Invoke(OnRead, this, e);
                else
                    OnRead(this,e);

            }
        }


        public void Write(string message)
        {
            try
            { 
                var buffer = Encoding.ASCII.GetBytes(message);
                MySocket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, null, null);
                if (OnWrite != null)
                {
                    var target = (Control)OnWrite.Target;
                    if (target != null && target.InvokeRequired)
                    {
                        target.Invoke(OnWrite, this, new EventArgs());
                    }
                    else
                    {
                        OnWrite(this, new EventArgs());
                    }
                }
            }
            catch
            {

            }
        }

Answers


BeginReceive asynchronously waits for a message and fills your buffer. You then start synchronously reading from the socket, overwriting the first message in the process.

You should call EndReceive which returns the number of bytes read, then process your buffer before trying to read more bytes.


I'm not sure if it's directly related to the problem, but you are using the Read method wrong. You are reading data into the buffer, but you are ignoring how much data was actually read assuming that the Read call always returns as much data as you request, so you are decoding the entire buffer eventhough it might not be completely filled.

Get the return value of the Read call so that you know how much of the buffer is actually filled with data:

int len = MyNetworkStream.Read(buffer, 0, buffer.Length);
string content = Encoding.ASCII.GetString(buffer, 0, len);

You need to implement EndRecieve to get the complete data from the stream. Checkout the following example from MSDN :

public static void Read_Callback(IAsyncResult ar){
    StateObject so = (StateObject) ar.AsyncState;
    Socket s = so.workSocket;

int read = s.EndReceive(ar);

if (read > 0) {
        so.sb.Append(Encoding.ASCII.GetString(so.buffer, 0, read));
        s.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, 0, 
                                 new AsyncCallback(Async_Send_Receive.Read_Callback), so);
}
else{
     if (so.sb.Length > 1) {
          //All of the data has been read, so displays it to the console
          string strContent;
          strContent = so.sb.ToString();
          Console.WriteLine(String.Format("Read {0} byte from socket" + 
                           "data = {1} ", strContent.Length, strContent));
     }
     s.Close();
}
}

Need Your Help

HMACSHA1 gives different output between JS and VB.Net

vb.net hmac hmacsha1

I'm trying to translate a JavaScript application of TOTP to VB.Net: http://blog.tinisles.com/2011/10/google-authenticator-one-time-password-algorithm-in-javascript/

Unable to start activity error with Scene2D

java android libgdx scene2d

We are trying to draw something with the scene2D from libGDX. We have our main activity then use the extends Androidapplication to initialize our testgame class. Here we define our screen and then ...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.