我想请一些关于这个案例的帮助。
我需要发送一条XDR消息,它由 2个文件组成( switch case == OK )。
假设我的代码中有一个名为message
的{{1}}对象:
response
如果我只需要在邮件中发送一个文件,我会这样做:
message response;
缓冲区为:
response.message_u.fdata.last_mod_time = last_modification;
response.message_u.fdata.contents.contents_len = file_size;
response.message_u.fdata.contents.contents_val = buffer;
现在,我了解buffer = malloc(file_size * sizeof(char));
它是一个可变大小的数组(2是最大长度),我希望它们的索引为struct file fdata<2>;
和something[0]
。
另外我知道我需要分配内存,但在这种情况下我不知道如何使用多个文件。
我是否需要为我需要发送的所有内容执行一个malloc?像这样:
something[1]
response.message_u.fdata.fdata_val = malloc ( (file_size1 * sizeof(char)) + (file_size2 * sizeof(char)) + (2 * sizeof(uint32_t)));
:每个要发送的文件的 last_mod_time
另一个问题是如何引用每个文件结构:
(2 * sizeof(uint32_t))
.x文件:
response.message_u.fdata[0] //?
response.message_u.fdata.last_mod_time[0] //?
response.message_u.fdata[0].last_mod_time //?
response.message_u.fdata.contents.contents_len[0] //?
response.message_u.fdata.contents.contents_val[0] //?
types.c(使用rpcgen生成):
enum tagtype {
GET = 0,
OK = 1,
QUIT = 2,
ERR = 3
};
struct file {
opaque contents<>;
unsigned int last_mod_time;
};
typedef string filename<256>;
union message switch (tagtype tag) {
case GET:
filename filenamedata<2>;
case OK:
struct file fdata<2>;
case QUIT:
void;
case ERR:
void;
};
感谢您阅读本文,并试图理解这一点。我真的很感激。
谢谢!
答案 0 :(得分:0)
要回答这个问题,我们可以更轻松地查看rpcgen从.x文件生成的类型:tagtype
,file
,filename
和message
。它们位于您未在问题中包含的xdr_types.h
中,因此我将rpcgen与您的.x文件一起使用。重要的是file
和message
:
...
struct file {
struct {
u_int contents_len;
char *contents_val;
} contents;
u_int last_mod_time;
};
typedef struct file file;
typedef char *filename;
struct message {
tagtype tag;
union {
struct {
u_int filenamedata_len;
filename *filenamedata_val;
} filenamedata;
struct {
u_int fdata_len;
struct file *fdata_val;
} fdata;
} message_u;
};
typedef struct message message;
...
回答你的两个问题:
如果我只需要在邮件中发送一个文件,我会这样做:
response.message_u.fdata.last_mod_time = last_modification; response.message_u.fdata.contents.contents_len = file_size; response.message_u.fdata.contents.contents_val = buffer;
缓冲区为:
buffer = malloc(file_size * sizeof(char));
和
另一个问题是如何引用每个文件结构:
response.message_u.fdata[0] //? response.message_u.fdata.last_mod_time[0] //? response.message_u.fdata[0].last_mod_time //? response.message_u.fdata.contents.contents_len[0] //? response.message_u.fdata.contents.contents_val[0] //?
不,response.message_u.fdata.
之后的部分是错误的。它可以是:
response.message_u.fdata.fdata_len
或
response.message_u.fdata.fdata_val
你的意思是第二个变体是struct file *fdata_val;
。对于那部分,你必须分配内存。
以下示例适用于2个文件,这些文件也将回答有关如何引用数据的问题:
// Set variables and allocate space for 2 file structures
message response;
u_int no_files = 2;
u_int file_size = 1024;
u_int last_mod_time = 42;
response.message_u.fdata.fdata_len = no_files;
response.message_u.fdata.fdata_val = malloc(no_files * sizeof(struct file));
// Access 1st file and allocate space for file content
response.message_u.fdata.fdata_val[0].last_mod_time = last_modification;
response.message_u.fdata.fdata_val[0].contents.contents_len = file_size;
response.message_u.fdata.fdata_val[0].contents.contents_val = malloc(file_size * sizeof(char));
// Access 2nd file and allocate space for file content
response.message_u.fdata.fdata_val[1].last_mod_time = last_modification;
response.message_u.fdata.fdata_val[1].contents.contents_len = file_size;
response.message_u.fdata.fdata_val[1].contents.contents_val = malloc(file_size * sizeof(char));
要了解有关XDR规范语言与生成的C输出之间关系的更多信息,请在SO:Understanding XDR specification to create a *.x file上获得此答案。
此外还有一本很好的书Power Programming with RPC by John Bloomer,它已经很老了(1991),但远程过程调用协议也是如此。本书是关于使用XDR发送/接收数据的RPC协议。 XDR语言(使用rpcgen,过滤函数等)在该书中有很好的描述。
以下是一些XDR规范: