Search code examples
c#socketstcptcpclientnetworkstream

Sending base64 string trough sockets doesnt completely arrive


In my application I wanted to implement profile pictures, so I started with a standard picture, which I converted to a byte array and then base64 string, however when the client requests the string from the server it doesnt fully arrive, the server reads the whole string from the database and sends it to the client, the client receives only a part of the string, this is the string(had to use pastebin): http://pastebin.com/ZmHhsZgG And this is the string the client receives: iVBORw0KGgoAAAANSUhEUgAAAEA This is how the server gets it from the database:

public string GetPP(string user)
    {
        CONN = new MySqlConnection();
        CONN.ConnectionString = Config.CONNSTRING;
        string query = "select * from members where username='" + user + "'";
        try
        {
            CONN.Open();
            COMMAND = new MySqlCommand(query, CONN);
            READER = COMMAND.ExecuteReader();
            string p = null;
            while (READER.Read())
            {
                 return p = READER.GetString("profilepic");
            }
            return p;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return "";
        }
        finally
        {
            CONN.Dispose();
        }
    }

then it sends it:

private void Do()
    {
        int requestCount = 0;
        byte[] bytesFrom = new byte[20025];
        string dataFromClient = null;
        Byte[] sendBytes = null;
        string serverResponse = null;
        string rCount = null;
        requestCount = 0;
        Responder.Responder R = new Responder.Responder();
        while ((true))
        {
            try
            {
                byte[] buffer = new byte[4];
                requestCount = requestCount + 1;
                NetworkStream networkStream = clientSocket.GetStream();
                buffer = new byte[4];
                int readBytes = networkStream.Read(buffer, 0, 4);
                if (readBytes == 0)
                    break;
                int MessageSize = BitConverter.ToInt32(buffer, 0);
                byte[] bufferreader = new byte[MessageSize];
                readBytes = networkStream.Read(bufferreader, 0, MessageSize);
                if (readBytes == 0)
                    break;
                dataFromClient = Encoding.ASCII.GetString(bufferreader);
                rCount = Convert.ToString(requestCount);
                byte[] outbuffer = new byte[4];
                serverResponse = R.Respond(dataFromClient);
                sendBytes = Encoding.ASCII.GetBytes(serverResponse);
                outbuffer = new byte[4];
                outbuffer = BitConverter.GetBytes(sendBytes.Length);
                networkStream.Write(buffer, 0, 4);
                networkStream.Flush();
                networkStream.Write(sendBytes, 0, sendBytes.Length);
                networkStream.Flush();
            }
            catch (Exception ex)
            {
                Console.WriteLine(" >> " + ex.ToString());
            }
        }
        Console.WriteLine("User Server >> " + "Client No:" + Convert.ToString(clNo) + " Stopped!");
    }

And the client receives:

            byte[] inbuffer = new byte[4];
            buffer = new byte[4];
            int readBytes = serverStream.Read(buffer, 0, 4);
            int MessageSize = BitConverter.ToInt32(buffer, 0);
            Console.WriteLine(Convert.ToString(MessageSize));
            byte[] bufferreader = new byte[MessageSize];
            readBytes = serverStream.Read(bufferreader, 0, MessageSize);
            string dataFromServer = Encoding.ASCII.GetString(bufferreader);
            if (dataFromServer.Contains("reauth"))
            {
                MessageBox.Show("Session Expired! Please Re-authenticate..");
                this.Close();
            }
            else
            {
                richTextBox1.Text = dataFromServer; //used to see what it receives
                MemoryStream mStream = new MemoryStream();
                byte[] pData = Convert.FromBase64String(dataFromServer);
                mStream.Write(pData, 0, Convert.ToInt32(pData.Length));
                Bitmap bm = new Bitmap(mStream, false);
                mStream.Dispose();
                pictureBox1.Image = bm;
            }
            clientSocket.Close();

Thanks in advance


Solution

  • I think the data isn't fully read because the 'buffer' variable which you send as the length indicator is not initialized to an updated value. I guess what you wanted to send was:

    serverResponse = R.Respond(dataFromClient);
    sendBytes = Encoding.ASCII.GetBytes(serverResponse);
    outbuffer = new byte[4];
    outbuffer = BitConverter.GetBytes(sendBytes.Length);
    **networkStream.Write(outbuffer , 0, 4);**
    networkStream.Flush();
    networkStream.Write(sendBytes, 0, sendBytes.Length);
    networkStream.Flush();