Write “complex” structures on a FIFO

元气小坏坏 提交于 2020-01-04 11:08:53

问题


I'm working a sort of "restaurant" implementation in C with client-server. I am trying to send the following structure through a FIFO:

   typedef struct { 
   int numtable;            //table number to send answer
   char timestamp[20];      //simple timestamp
   int order[MENUSZ];       //array of int with dish IDs
   } request;

About this struct, I basically send to the server the table number, to "build" the client FIFO name through a template, a timestamp, and order is a simple array filled with randomly chosen integers to "create" a sort of random menu request. With this setup I didn't have problems, using

   write(server_fd, &request, sizeof(request))

I had problems when I wanted to transform the array order[MENUSZ] in a pointer, to make a dynamic array, like this:

    typedef struct {    
   int numtable;            
   char timestamp[20];      
   int *order;      
   } request;

After changing the struct, I used the malloc function to allocate enough space for the array:

   request->order = malloc(sizeof(int)*numclients+1);

The array is fullfilled correctly, but for some reason the server can't read from the FIFO after I added this pointer, by doing

   read(server_fd, &request, sizeof(request));

I can't figure out why it doesn't work with this pointer. Am I doing something wrong?


回答1:


The array is fullfilled correctly, but for some reason the server can't read from the FIFO after I added this pointer, by doing

read(server_fd, &request, sizeof(request));

You are transferring your structure, which includes a pointer, and the value of the pointer will be transferred correctly, but it will not point to a valid address in the destination process, neither will there be memory allocated where the pointer points to.

Hence, you need to transfer the array separately and recreate the pointer in the destination process, something like:

read(server_fd, &request, sizeof(request));

/* allocate memory for request->order in the reader process */
request->order = malloc(sizeof(int)*numclients+1);
read(server_fd, request->order, sizeof(int)*numclients+1);

A yet better solution would be to also transfer the size of the array inside your structure.

On the sending side, you then need to send both, the structure and the array contents, something like

write(server_fd, &request, sizeof(request))
write(server_fd, request->order, sizeof(int)*numclients+1));



回答2:


It is because sizeof(request) no longer tells you the size of the combined structure. Try this

typedef struct {    
   int numtable;            
   char timestamp[20];      
   int order[1];      
} request;

When you have a new request

int reqsize = sizeof(request) + sizeof(int) * numclients;
request* req = malloc(reqsize);

This allows you to use req->order[1] to req->order[numclients - 1]. When you send it, use

 write(server_fd, reqsize, sizeof(int))
 write(server_fd, req, reqsize)

When reading

read(server_fd, &reqsize, sizeof(int))

Then allocate the request before reading

request* req = malloc(reqsize)
read(server_fd, req, reqsize)

This technique uses "the chumminess of C" http://c-faq.com/struct/structhack.html, which, as far as I know, works on all implementations of C.



来源:https://stackoverflow.com/questions/26235345/write-complex-structures-on-a-fifo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!