How do I keep reading data from my Socket to append my buffer

Viewed 137

So I'm trying to send an image from my client to my server and I'm sending the entire image as a whole, meaning that I'm not splitting it up into chunks, I'm just sending the entire byte array as is.

CLIENT

private void SendImage(byte[] opcode, byte[] length, byte[] payload)
{
    var packet = new byte[payload.Length + length.Length + 1];
    Array.Copy(opcode, 0, packet, 0, 1);

    //Set the length
    Array.Copy(length, 0, packet, 1, length.Length);


    Array.Copy(payload, 0, packet, 5, payload.Length);
    _clientSocket.Send(packet);
}

This sends just fine, I'm using the OpCode 0x15 which will be interpreted by the server as "there is an image incoming". The length is the payload.Length which I've done this with

var length = BitConverter.GetBytes(myImage.Length);

So it occupies 4 bytes.

So my packet structure looks like this OpCode(1 byte), Length(4 bytes), Payload(imageBytes)

This method works just fine, it sends without any issues what so ever, I only included the code for it so that the next part will make sense.

SERVER

private byte[] _buffer = new byte[1024];
private void ReceiveCallback(IAsyncResult ar)
{
    var client = (Socket)ar.AsyncState;
    int received = client.EndReceive(ar);

    //Temporary buffer
    var dataBuf = new byte[received];
    Array.Copy(_buffer, dataBuf, received);

    
    switch (dataBuf[0])
    {
        //Received image
        case 0x15:
            //Read the packet header and check the length of the payload
            var length = BitConverter.ToInt32(dataBuf.Skip(1).Take(4).ToArray(), 0);

            //This will hold the bytes for the image
            var imageBuffer = new byte[length];

            //First incoming packet payload (image bytes)
            var imgData = dataBuf.Skip(5).ToArray();

            //Copy that into the buffer
            Array.Copy(imgData, 0, imageBuffer, 0, imgData.Length);


            var pos = imgData.Length;
            //Keep reading bytes from the incoming stream
            while (dataBuf.Length > 0)
            {
                imgData = new byte[1024];
                client.Receive(imgData);
                Array.Copy(imgData, 0, imageBuffer, pos, dataBuf.Length);
                pos += 1024;
            }

            //This takes the bytes and creates a bitmap from it
            AnotherViewModel.SetImage(imageBuffer);
            break;

        default:
            Debug.WriteLine("Wat");
            break;
    }

    client.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), client);

}

The issues I'm facing is that I don't know how to keep appending the incoming data to the imageBuffer because I want to receive the full image and not just the first 4 bytes and with my while loop I'm currently getting this exception

Destination array was not long enough. Check destIndex and length, and the array's lower bounds.

Over at this line Array.Copy(imgData, 0, imageBuffer, pos, dataBuf.Length);

How do I properly read the entire image that the client sends to the server?

0 Answers
Related