none
Byte Array size. RRS feed

  • Question

  • I'm sending a video frame from a server to  a client. Now I know what size Byte array I should declare on the server side in which I'll store the picture and send it, however, I dont know what size array I should declare on the client side. Is there any way of finding out exactly how much data is coming in before i declare the array in which data will be stored? It proving impossible to display that picture. One more thing, should i worry about the picture/frame header?
    Saturday, February 3, 2007 2:36 PM

All replies

  •  Umair-Shahzad wrote:

    I'm sending a video frame from a server to  a client. Now I know what size Byte array I should declare on the server side in which I'll store the picture and send it, however, I dont know what size array I should declare on the client side.  Is there any way of finding out exactly how much data is coming in before i declare the array in which data will be stored?

    You have to send 4 byte preceeding the picture data, which will contain information about the packet coming in its back. receiver will read these 4 byte (int) create a buffer of that size and read all data in that buffer...

    You packet will somehow form like this:

                       Picture Data                                 Size

    3425987357349538427594327597439     34

    Client will read size, which is 34 now it'll crate buffer (byte[] buffer = new byte[34]) and read all that data in it.

    To do this do something like:

    Sending:

    1. Grab picture
    2. Convert to Bytes.
    3. Count Number of bytes and store that count in some in variable.
    4. Convert that int into bytes using BitConvertor class's function.
    5. Write those count bytes on Network.
    6. Write the actual Frame.

    Receiving:

    1. Read Count bytes.
    2. Convert them to int.
    3. Create buffer of that count size
    4. Read only that much bytes next from the network.
    5. Convert again to picutre and display it.

     Umair-Shahzad wrote:

     One more thing, should i worry about the picture/frame header?

    What do you mean by this?

    Best Regards,

    Rizwan aka RizwanSharp

     

    Saturday, February 3, 2007 3:39 PM
  • Thanks a lot for replying. I did what you said and now i know exactly what size the picture is, only, i'm still unable to display the picture. Now i think it might have something to do with the header. A header of a picture contains information such as what the size of the picture is, what the format is etc. 
    If you think i need to change something in the client side code, please tell me.

    Byte[] countbytes = new Byte[ 8];
    int noofbytes = s.Read(countbytes, 0, countbytes.Length);
    long size = BitConverter.ToInt64(countbytes, 0);
    Byte[] pic = new Byte[size];
    long receive = s.Read(pic, 0, pic.Length);
    MemoryStream ms = new MemoryStream(pic);
    Image finalImage = Image.FromStream(ms);
    pictureBox1.Image = finalImage;

     

    Sunday, February 4, 2007 10:16 AM
  • No Header is not a problem as far as you send complete bytes of image.
    Try this:

    Byte[] countbytes = new Byte[ 8];
    int noofbytes = s.Read(countbytes, 0, countbytes.Length);
    long size = BitConverter.ToInt64(countbytes, 0);
    Byte[] pic = new Byte[size];
    long receive = s.Read(pic, 0, pic.Length);
    MemoryStream ms = new MemoryStream(pic);

    Image finalImage = Image.FromStream(ms);
    pictureBox1.Image = finalImage;

    I hope this will work fine.

    Best Regards,

    Rizwan aka RizwanSharp



    Sunday, February 4, 2007 1:23 PM
  • Still not working. What if i insert an end of file string in the last few bytes of the picture array on the server side and upon receiving the data, check for that particular string and THEN display the image? Will it work? By the way, how should i check what the last few bytes of an array are?
    Sunday, February 4, 2007 5:39 PM
  • I just checked, writing to MS with array of bytes in construction will still keep it's position to be 0 so my last post will not make any difference. I think you are mising some bytes from picture, specially from the picture header,  that's making picture not be displayed.

    Make sure you are sending and receiving whole bytes with same values.

    e.x

    Send:

    3,5,66,78,5,32,4,6,7

    Receive the same number of bytes with same values.

    This is the only thing i can suggest without seeing your whole code.

    Best Regards,

    Rizwan aka RizwanSharp

    Sunday, February 4, 2007 6:02 PM
  • Thanks again for replying. I have checked whether I am receiving the whole thing or not, apparently i am. Now the bit of code which is supposed to make an image out of a MemoryStream is throwing a "Parameter Not Valid" Exception. Rest seems fine. I'm hoping against hope that fixing this might actually make it work. I am pasting the relevant client/server side code below.

    Server Side:

    Int32 Port = 13000;
    IPAddress localAdd = IPAddress.Parse("127.0.0.1");
    server =
    new TcpListener(Port);
    server.Start();
    textBox1.Text =
    "Waiting to connect....";
    while (true)
    {
    client = server.AcceptTcpClient();
    textBox1.Text =
    "Connected!!!";
    while (client.Connected)
    {
    NetworkStream stream = client.GetStream();
    MemoryStream ms = new MemoryStream();
    tempObj =
    Clipboard.GetDataObject();
    tempImg = (System.Drawing.
    Bitmap)tempObj.GetData(System.Windows.Forms.DataFormats.Bitmap);
    //Get the Webcam Image
    x.WebCamImage = tempImg.GetThumbnailImage(m_Width, m_Height, null, System.IntPtr.Zero);
    //Save it to a memory stream
    x.WebCamImage.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
    Byte[] photo = new Byte[ms.Length];
    photo = ms.ToArray();
    long input;
    input = photo.Length;
    Byte[] output = BitConverter.GetBytes(input);
    //Send the size of the image
    stream.Write(output, 0, output.Length);
    //Send the image. A delay to slow things down and try to find out whats wrong.Will remove it when it starts working
    Thread.Sleep(1000);
    stream.Write(photo, 0, photo.Length);
    Thread.Sleep(1000);
    }
    server.Stop();

    Client Side:

    Int32 Port = 13000;
    IPAddress localAddr = IPAddress.Parse("127.0.0.1");
    TcpClient client = new TcpClient();
    while (!(client.Connected))
    {
    try
    {
    client.Connect(localAddr, Port);
    }
    catch
    {
    }


    }
    Stream s;
    s = client.GetStream();
    while (client.Connected)
    {
    Byte[] countbytes = new Byte[ 8];
    s.Read(countbytes, 0, countbytes.Length);
    long size = BitConverter.ToInt64(countbytes, 0);
    Byte[] pic = new Byte[size];
    MemoryStream ms = new MemoryStream(pic);
    //PARAMETER NOT VALID EXCEPTION

    Image finalImage = Image.FromStream(ms);
    pictureBox1.Image = finalImage;
    }

    client.Close();

    Monday, February 5, 2007 9:21 AM
  • If you can send both client and server's code into my email, It'll be better for me to check the complete story.

    My hotmail account is showing some problem, so you can send it to my yahoo one rizwansharp@yahoo.com.nospam. Remove the nospam.

    And better if you send me an sms which will tell me that your email is there so i can check at +92-322-5024482.

    I'll try my best to do whatever I could do.

    Best Regards,

    Rizwan aka RizwanSharp

    Monday, February 5, 2007 12:27 PM
  • I ran into the same problem of the parameter not valid exception.

    I resolved this by enlargning the buffer size. this code works perfectly to send over images smaller then the buffersite (lets say 512kb).

    private void HandleClientComm(object client)
            {
                TcpClient tcpClient = (TcpClient)client;
                NetworkStream clientStream = tcpClient.GetStream();

                byte[] message = new byte[524288];
                int bytesRead;

                //while (true)
                while (clientStream.CanRead)
                {
                    bytesRead = 0;

                    try
                    {
                        //blocks until a client sends a message
                        bytesRead = clientStream.Read(message, 0, 524288);
                    }
                    catch
                    {
                        //a socket error has occured
                        break;
                    }

                    if (bytesRead == 0)
                    {
                        //the client has disconnected from the server
                        break;
                    }

                    MemoryStream ms = new MemoryStream(message,0,bytesRead);
                   
                    Image resultImage = Image.FromStream(ms);
                    resultImage.Save("c:\\resultImage.jpg");

                    MessageBox.Show("done");
                }

                tcpClient.Close();
            }

    Wednesday, July 15, 2009 12:57 PM