Click here to Skip to main content
14,929,248 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have an array of 530 bytes.
I would like to split it into uneven chunks.

Namely, I'd like to split it at elements 1, 3, 5, 7, 9, 265, 521, 523, 525, 527, 529.
Then I want to do some data conversion on the new "chunks".

Is there any easy way preform such split operation?

What I have tried:

I was trying to write my array into a MemoryStream, and then try doing something like:
public partial class Form1: Form
{
    public MemoryStream memStream = new MemoryStream(2000);
    Byte[] bytesFromTCP = new Byte[530];

    public byte[] arrInt1 = new byte[2];
    public byte[] arrBool1 = new byte[2];
    public byte[] arrBool2 = new byte[2];
    public byte[] arrBool3 = new byte[2];
    public byte[] arrBool4 = new byte[2];
    public byte[] arrString1 = new byte[256];
    public byte[] arrString2 = new byte[256];
    public byte[] arrBool5 = new byte[2];
    public byte[] arrBool6 = new byte[2];
    public byte[] arrBool7 = new byte[2];
    public byte[] arrCrc = new byte[2];

    public void bgWorkerSocketListener_DoWork(object sender, DoWorkEventArgs e) 
    //Start the TCP Listener
    {
        try
        {
            AppendTextBox2("Waiting for a connection... ");

            server = new TcpListener(localAddr, port);

            server.Start();

            //Byte[] bytes = new Byte[530];

            String data = null;

            while (true)
            {
                client = server.AcceptTcpClient();
                AppendTextBox2("Connected!" + Environment.NewLine);

                data = null;

                NetworkStream stream = client.GetStream();
                int i;
                while (client.Connected == true)
                {
                    lblTcpStatusBottom.Text = "PLC: Connected";
                    lblTcpStatusBottom.ForeColor = Color.Green;
                    try
                    { 
                        // Loop to receive all the data sent by the client.
                        while ((i = stream.Read(bytesFromTCP, 0, 
                                                  bytesFromTCP.Length)) != 0)
                        {
                            // Translate data
                            data = BitConverter.ToString(bytesFromTCP);
                            
                            AppendTextBox2("Data:"+data +"Length: "+ data.Length);

                            memStream.Write(bytesFromTCP, 0, bytesFromTCP.Length);
                            this.Invoke(new EventHandler(processMessageMemStr));
                        }
                    }
                    catch (Exception ex)
                    {
                        lblTcpStatusBottom.Text = "PLC: Disconnected!";
                        lblTcpStatusBottom.ForeColor = Color.Red;
                        RestartServer();
                    }
                }
            }
        }
        catch (SocketException ex)
        {
            MessageBox.Show("SocketException: " + ex);
        }
    }//bgWorker

    private void processMessageMemStr(object sender, EventArgs e) //Process memStream 
    {
        try
        {
            memStream.Seek(0, SeekOrigin.Begin);
            memStream.Read(arrInt1, 0, 1);
            memStream.Read(arrBool1, 2, 3);
            memStream.Read(arrBool2, 4, 5);
            memStream.Read(arrBool3, 6, 7);
            memStream.Read(arrBool4, 8, 9);
            memStream.Read(arrString1, 10, 265);
            memStream.Read(arrString2, 266, 521);
            memStream.Read(arrBool5, 522, 523);
            memStream.Read(arrBool6, 524, 525);
            memStream.Read(arrBool7, 526, 527);
            memStream.Read(arrCrc, 528, 529);

            MessageBox.Show(Convert.ToString(arrInt1));
        }
        catch (Exception err)
        { MessageBox.Show(err.ToString()); }
    }
}

I know bytesFromTCP contains a full message, because using BitConverter.ToString() I can display it in a textBox. But when trying memStream.Read() I'm getting an exception saying that buffer cannot be null, like my array wasn't written to the MemoryStream
Any help would be greatly appreciated.

Edit:
So now I'm getting an error here:
memStream.Read(arrBool1, 2, 3);

Offset and length out of bounds for the array or count is greater than the number of elements from index to the end of the source collection. At System.IO.MemoryStream.Read(Byte[] buffer, Int32 offset, Int32 count)
Posted
Updated 28-Feb-21 12:07pm
v5
Comments
[no name] 27-Feb-21 9:47am
   
Most probably your arrInt1 (and all the other buffers) is null?
Member 14827175 27-Feb-21 11:00am
   
Yeah they were, I initialized them all but now I'm getting an error saying: Offset and length out of bounds for the array or count is greater than the number of elements from index to the end of the source collection. At System.IO.MemoryStream.Read(Byte[] buffer, Int32 offset, Int32 count)
Gerry Schmitz 27-Feb-21 11:34am
   
Don't see any code that initializes your "chunks" (i.e. "buffers"). You also seem to assume the stream is "correctly" "positioned" for reading.

Note: "Solutions" around here are more like comments: "try this" ... "try that".

Nobody seems to have suggested checking the stream's "length".
Member 14827175 27-Feb-21 11:48am
   
Good suggestion, just checked the length, it's as expected - 530. But with each iteration it doubles, should I be flushing/clearing it in someway?

It looks you did not create the buffers for arrInt1 (and all the others).

At least for me

a.) this one fails with the error message you mentioned:
Byte[] arrInt1= null;
Byte[] bytesFromTCP = new Byte[530];
MemoryStream memStream = new MemoryStream();
memStream.Write(bytesFromTCP, 0, bytesFromTCP.Length);
memStream.Read(arrInt1, 0, 1);  // <= Fails here as you mentioned

b.) This one works
Byte[] arrInt1= new byte[128];
Byte[] bytesFromTCP = new Byte[530];
MemoryStream memStream = new MemoryStream();
memStream.Write(bytesFromTCP, 0, bytesFromTCP.Length);
memStream.Read(arrInt1, 0, 1); // <= Works, because arrInt1 is created
   
v4
Comments
Member 14827175 27-Feb-21 10:46am
   
So I created buffers for my arrays like so:
public byte[] arrInt1 = new byte[128];
public byte[] arrBool1 = new byte[128];
public byte[] arrBool2 = new byte[128];
public byte[] arrBool3 = new byte[128];
public byte[] arrBool4 = new byte[128];
public byte[] arrString1 = new byte[256];
public byte[] arrString2 = new byte[256];
public byte[] arrBool5 = new byte[128];
public byte[] arrBool6 = new byte[128];
public byte[] arrBool7 = new byte[128];
public byte[] arrCrc = new byte[128];
Now the Exception says: Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection Are the array buffers too big? I also added memStream.Seek( 0, SeekOrigin.Begin ); as suggested by @BillWoodruff
[no name] 27-Feb-21 11:04am
   
Please post your current code in your question. And btw. this length of 128 for the buffer was only a 'random' size to be on the safe side. Now it really depends how much bytes you read 'per read' and this should never be that 128 byte it shluld only be the size you need for the specific items (sorry, my English is bad, I know:( )
Member 14827175 27-Feb-21 11:19am
   
OK, I'll update my question with some more details, thanks. And your English is perfectly splendid ;)
[no name] 27-Feb-21 11:22am
   
*blush* it is not, but thank you :-)
Try:

memStream.Position = 0;

or:

memStream.Seek( 0, SeekOrigin.Begin );

before the first read. see: [^]
   
Comments
[no name] 27-Feb-21 10:26am
   
No vote from here (even it deserves at max a 3), but a comment. 'buffer cannot be null' has nothing to do with current stream position.
Member 14827175 27-Feb-21 11:02am
   
Sorry @BillWoodruff, I should have mentioned that I was already using memStream.Seek( 0, SeekOrigin.Begin ); Thanks for the suggestion nonetheless.
Instead of:
try
{
    memStream.Seek(0, SeekOrigin.Begin);
    memStream.Read(arrInt1, 0, 1);
    memStream.Read(arrBool1, 2, 3);
    memStream.Read(arrBool2, 4, 5);
    memStream.Read(arrBool3, 6, 7);
    memStream.Read(arrBool4, 8, 9);
    memStream.Read(arrString1, 10, 265);
    memStream.Read(arrString2, 266, 521);
    memStream.Read(arrBool5, 522, 523);
    memStream.Read(arrBool6, 524, 525);
    memStream.Read(arrBool7, 526, 527);
    memStream.Read(arrCrc, 528, 529);
}
I did:
try
{
    memStream.Position = 0; //memStream.Seek(0, SeekOrigin.Begin) SameButLonger?
    memStream.Read(arrInt1, 0, 2);
    memStream.Read(arrBool1, 0, 2);
    memStream.Read(arrBool2, 0, 2);
    memStream.Read(arrBool3, 0, 2);
    memStream.Read(arrBool4, 0, 2);
    memStream.Read(arrString1, 0, 256);
    memStream.Read(arrString2, 0, 256);
    memStream.Read(arrBool5, 0, 2);
    memStream.Read(arrBool6, 0, 2);
    memStream.Read(arrBool7, 0, 2);
    memStream.Read(arrCrc, 0, 2);
}
I misunderstood the 'offset' and 'count' functions of memStream.Read()
This works like it's supposed to.

I tested it with:
MessageBox.Show(memStream.Capacity.ToString() + "\n" + memStream.Length.ToString() + "\n" + memStream.Position.ToString());
And could see the 'count' was moving up all the way up to byte no. 530

At the end I was able to display data with:
MessageBox.Show(BitConverter.ToString(arrInt1) + "\n" + BitConverter.ToString(arrBool1) + "\n" + BitConverter.ToString(arrBool2) + "\n" + BitConverter.ToString(arrBool3) + "\n" + BitConverter.ToString(arrBool4) + "\n" + BitConverter.ToString(arrString1) + "\n" + BitConverter.ToString(arrString2) + "\n" + BitConverter.ToString(arrBool5) + "\n" + BitConverter.ToString(arrBool6) + "\n" + BitConverter.ToString(arrBool7) + "\n" + BitConverter.ToString(arrCrc));
And confirm every byte was correctly placed.

Thanks for the help everyone
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900