How can i Concatenate memory blocks - arrays

I need a requirement where in i need to Concatenate memory blocks
I'm sending my data from UDP as chunks of 100 bytes, and i have verified the transfer, but when I send a 800 bytes array as 8 chunks, and Concatenate them to an array I'm not able to retrieve data
im sending an int array of 200 elements which comes to 800 bytes and the first element is being incremented to check data
my simple logic goes like this
// allocate memory for main memory block
void* rcv_Data = malloc(800);
// allocate memory for chunk memory block
void* tempdata = malloc(100);
// read all 8 chunks
for (int ndx=0; ndx<8;ndx++)
{
Read_packet(skt,tempdata,100);
memmove((rcv_Data +(ndx*100)) ,tempdata, 100);
}
printf("data is %d\n",((int*)rcv_Data )[0]);
but my data being printed is 0 all time , but actual data is a incrementing number
my read function is as follows
int Read_packet(int CSPL_Socket, void *buf,int datalen)
{
int numb_bytes=0;
numb_bytes=read(CSPL_Socket, buf, datalen);
if(numb_bytes<0)
{
CSPL_SOK_ERROR(-6);
close(CSPL_Socket);
exit(1);
return -1;
}
else
{
//printf("Count %d\n",numb_bytes);
}
return 0;
}
i have just posted small portion of code , just not to make it too long and complicate, i need advice on whether this logic is correct or not

Related

How to allocate memory in the front of data

I am working with sending data to and from a client/server application. I have created my own header scheme. This is the flow I am in question about:
char *data = returnmydata();
int one = 1;
int two = 2;
int three = 3;
So what happens is I have a char buffer that contains all my data. But I need to append to the front of this data my one, two, and three integers which is used to let the other side know how to handle the data.
Instead of allocating enough at the start for the 3 header items, is it possible to reallocate an addition 12 bytes and move the start of the data to data+12?
I currently just memcpy the 3 integers at the start then offset the data +12. However I think my code would be better if I could just pass a struct that contains the 3 ints and a pointer to the data. Then I can use this function to create the full data buffer with the headers in it.
Another option is to alloc another buffer memcpy the 3 integers to the front, and then memcpy the data to the new buffer. However I would like to keep memory usage low.
Use functions realloc and memmove.
If the size of the initially allocated buffer is equal to some value N then you can write
char *tmp = realloc( data, N + 12 );
if ( tmp != NULL )
{
data = tmp;
memmove( data + 12, data, N );
// then you can insert some values in the first 12 bytes of the allocated buffer
}

sending an array of structs across a socket

What if I had a an array of struct. Is it possible for me to send an array of structs over a socket? The struct size will be updated continuously and at any time I would be able to print out the content of the structs. I hope this makes sense, my explanation might not be cleared. My syntax is definitely not correct for some areas, it's just a snippet of what I think it would look like. I just need some guidance.
This will send the array of structs acorss the socket.
void sendOpenMessage(int num0, int num1, int num2){
struct openMessage{
int num0;
int num1;
int num2
};
struct openMessage open[100];
int i = 0;
open[i].num0 = 1;
open[i].num1 = 2;
open[i].num2 = 3;
int length = sizeof(open);
if(send(socket, &open[i], length, 0) == -1){
fprintf(stderr, "Send() failed");
}else{
printf("Open message is being sent\n");
}
i++;
}
This will receive the struct and display the contents in a message
struct openMessage open[100];
if(recv(clnSocket, &open, sizeof(open), 0) < 0){
fprintf(stderr,"Recv() failed\n");
printf("Error code: %d\n", errno);
}
//Get size of the current struct
//Print out the messages from the structs that have messages?
void printStruct(struct openMessage open){
for(int i = 0; i < sizeof(the struct); i++){
printf("%d\n",open[i].num0);
printf("%d\n", open[i].num1);
printf("%d\n", open[i].num2);
}
}
First of all, you need to read up about byte ordering and serialisation.
Secondly, length is the size of the whole array, so when i is zero you send the whole array, when i is 1 you send all but the first element plus some garbage at the end, and so on.
Thirdly, when receiving you iterate across sizeof(the struct) members of the array. Don't you want to iterate across the whole array?
When you say the struct size will be updated continuously, do you mean the number of elements in the array? Your struct has a fixed size.
If you are sending variable quantities of data, i.e. if you want to send a piece of data that has one length at one time and another length at another time, or even if you want the number of elements in the array to update dynamically, then you MUST send that size across the socket, and send it before the data. Send the size first, read it first on the receiving end, and then the receiving end will know how much more data to read, and more importantly, where the data ends so that if there is more data later it doesn't all get mixed up.

Save certain number of bytes from a file into a specific memory adress

I have open a file and I know how to read the number of bytes that I want for it but now I want to save that bytes into a specific adress from memory and i dont know how I can do that.
The following code is what i have:
void fileSaver(char * n []){
int fil;
int bytes;
char * space = malloc(100);
fil= open("file",O_RDONLY);
bytes=read(fil,space,4);
printf("%d\n",bytes );
printf("%s\n",space );
}
the n that I use as parameter for the function is the number of bytes that I want to read

Not getting the right values when copying structs

A buffer that holds binary chunks of data is supposed to be copied to an array of structs (each struct represents a chunk), each chunk in the buffer is 20 bytes, first 4 bytes hold the hash value, then 8 bytes for an offset info, then 8 for a size:
thats the struct definition:
typedef struct{
khint_t hash; // 4
long int offset_start; // 8
size_t size; // 8
} header_offset, *offset_p;
and below is the code that's supposed to do whats mentioned:
offset_p *offsets;
size_t s= HEADER_OFFSET_SIZE;
header_offset t_offsets[n_files];
for (i=0; i< n_files; i++){
memcpy(&t_offsets[i].hash, buff, sizeof(khint_t));
buff+= sizeof(khint_t);
memcpy(&t_offsets[i].offset_start, buff, sizeof(long int));
buff+= sizeof(long int);
memcpy(&t_offsets[i].size, buff, sizeof(size_t));
buff+= sizeof(size_t);
printf("hash read: %p\n", t_offsets[i].hash);
printf("offset start read: %p\n", t_offsets[i].offset_start);
printf("offset size read: %p\n", t_offsets[i].size);
}
memmove(offsets, t_offsets, sizeof(header_offset)*n_files);
buff-= s*n_files;
free(buff);
return offsets;
I was struggling copying the chunks directly into a header_p* so i decided to have a temporary struct array thats copied from the buffer, then gets copied to a header_p*, I'd appreciate it even more if you could provide me with a way to do it without using a temporary struct array.
The printfs print the right data, although when calling this function, the array of the pointers returned does not hold the right data, or the same data that was printed within the loop.
I'd like to know, without further code, whether its the way im using pointers that causes the array of offset_p's not hold the right values.
No memory has been allocated for offsets, memmove() does not allocate the memory for you:
header_offset* offsets = malloc(sizeof(header_offset)*n_files);
Given that your are allocating memory to be returned the use of t_offsets is unrequired: just populate offsets directly.
EDIT:
To return a header_offset*[] as commented by alk:
header_offset** offsets = malloc(sizeof(header_offset*) * n_files);
for (i=0; i< n_files; i++){
*(offsets + i) = malloc(sizeof(header_offset));
...
}
offsets is supposedly an array of pointers, not structs.
The memcopy will probably overwrite a large chunk of memory past the end of the memory allocated for offsets (allthough we can't see how much memory was allocated for it).
I'd suggest:
offset_p *offsets = (offset_p*)malloc(sizeof(offset_p)*n_files);
And then a loop
for (i=0; i< n_files; i++){
offsets[i] = malloc(sizeof(header_offset));
memcpy(&(*offsets[i]).hash, buff, sizeof(khint_t));
buff+= sizeof(khint_t);
memcpy(&(*offsets[i]).offset_start, buff, sizeof(long int));
buff+= sizeof(long int);
memcpy(&(*offsets[i]).size, buff, sizeof(size_t));
buff+= sizeof(size_t);
}
To return an array of pointers to header_offset the array itself needs to be allocated (then referenced by offset_p *offsets;
) as well as the memory holding the data currently held by the temporary structures. The latter then will be references by the pointers held by offsets.

Appending to dynamically allocated array

I am trying to add data received onto a buffer which needs to be configurable at runtime (I read a size from file or command line).
So basically I determine my buffersize and allocate an area of memory using calloc (I also put a catchall to set a buffersize if it is not in the config file or command line - Let's assume we use that for now).
I am only putting applicable lines of code.
int buffersize=10000;
void *BuffPtr = (void *)calloc(1,buffersize * sizeof(char));
I then have a recv from UDP (I have tried receiving into char array and dynamically allocated array - both work fine)
// Setup socket......
void *PktBuff = (void *)calloc(1,1000 * sizeof(char));
// Loop and receive many packets......
rcvd_bytes=recv(recv_socket, PktBuff, 1000, 0);
I can, at this point, write the contents of PktBuff and it works fine. But I want to concatenate a number of received packets in my dynamically allocated array (BuffPtr defined above).
I have tried strcat, but I just get garbage out if I try to write the first packet received, without getting another packet.
strcat(BuffPtr, PktBuff);
What I am doing wrong??
Thanks in advance.
Your data doesn't seem to be 0-terminated strings, you may want to use memmove instead.
A few points and observations:
Don't cast the return value of malloc() in C.
The expression sizeof (char) is a wordy way of writing 1, multiplying by it is seldom informative.
Make sure all your data is 0-terminated (strings), otherwise you can't use string functions since that's what they require.
You should probably just use an extra size_t counter to keep track of the number of bytes in BuffPtr, and use that and memcpy() to append.
Okay a number of issues in your code strcat is NOT the right way to append binary data. Here is a semi-robust implementation. I have NOT checked it for syntax errors, just typed it out please study it as an example, and adjust it to your code.
/* total number of bytes you are willing to receive in single a single receive */
#define MAX_RECV_BUFFER 1000
/* total number of bytes you are willing to store in memory */
#define MAXBYTES MAX_RECV_BUFFER*1000
int append_bytes() {
char rcvbuf[MAX_RECV_BUFFER]; /* buffer where things are received */
void *buf = NULL; /* buffer where bytes are collected */
size_t rcvlen; /* length of data received */
size_t buflen = 0; /* total bytes */
while(1) {
void *p;
rcvlen = recv(recv_socket, rcvbuf, MAX_RECV_BUFFER, 0);
if ( rcvlen < 0 ) { manage_error(); }
if ( rcvlen == 0 )
break;
if ( buflen + rcvlen > MAXBYTES)
break;
p = realloc(buf, buflen+recvlen);
if ( !p ) { manage_memory_error(); }
buf = p; /* we have enough space */
memcpy(buf+buflen, rcvbuf, recvlen); /* append new content to end of buffer */
buflen+=recvlen; /* add length to buflen */
}
}

Resources