0

I'm writing code that dealing with data received from udp in application layer.

This is the function prototype used for receiving data from udp

int my_recv_UDP(int s,
                void* mem,
                int len,
                struct sockaddr* from,
                int fromlen);

in which it uses s as socket, puts data in mem with length len, and returns data length which's value might less then len.

For example

frameLen = my_recv_UDP(socket, rxBuf, 100, &ra, sizeof(ra));

in which it uses socket as socket, put data in rxBuf with length 100, and returns data length to frameLen.

Original data length might bigger or less then 100. Since you specify length value with 100, you might get data length less then 100 this time or loss data following order 100 next time, depending on frame.

I intended to create a data type by a struct and let this struct type's ptr to point to rxBuf.

i.e:

typedef struct{
    int cmd;
    int data[?];    //you don't know the data length until you receive data
    int len;
}rxBuf_s;

So, I can do like this.

rxBuf_s* rxBuf_p = rxBuf; 

With this, I can "manipulate" data in rxBuf easily, for example, if I want to read cmd into buffer:

int Cmd = rxBuf_p->cmd;

But I didn't know the data length until I receive it, I don't know what offset is len either, So decided to calculate the length in "run time" and put it in array, like:

typedef struct{
    int cmd;
    int data[length];    //length is calculated in run time.
    int len;
}rxBuf_s;

But VLA in struct is not allowed in C99.
How can I do? Is there any smart way to do this?

Andy Lin
  • 397
  • 1
  • 2
  • 21
  • Either use the maximum length that ever could be reached, or change data to a pointer int*. – Klaus Gütter Dec 22 '18 at 07:20
  • You are misunderstand. I've changed the content, plz read it again. – Andy Lin Dec 22 '18 at 07:27
  • Ahh, maybe I understand now. So you receive `cmd, data[length], len` in this order in the frame? Then you are out of luck mapping all three to a common struct. You need to calculate the offset of the `len` member explicity and extract it from the receive buffer. – Klaus Gütter Dec 22 '18 at 07:53
  • Yes, in this order. But the problems is, C99 does not allow me to calculate the offset of the len member and put it in array data. English is not my mother tongue, plz bear with me of bad English. Btw, how to put shaded text in comment? – Andy Lin Dec 22 '18 at 08:14
  • Read about [flexible array member](https://en.wikipedia.org/wiki/Flexible_array_member). It has to be the *last* in its containing `struct` – Basile Starynkevitch Dec 22 '18 at 11:23

1 Answers1

2

So you receive cmd, data[length], len in this order in the frame. As you already noted, it is not possible to catch this 1:1 using a C structure. At least the len field has to be extracted by a different means, e.g.

length = ...; // calculate length

int cmd = *(int*)rxBuf;
int *data = (int*)rxBuf + 1;
int len = *(data + length);
Klaus Gütter
  • 11,151
  • 6
  • 31
  • 36