通过SunRPC(c)发送带缓冲区的链表

通过SunRPC(c)发送带缓冲区的链表,c,struct,linked-list,rpc,C,Struct,Linked List,Rpc,在过去的几天里,我一直在为以下事情伤脑筋:我想通过SunRPC发送任何大小/类型的文件。在客户端,我将文件读入一个链表,每个节点包含一个大小为1024的缓冲区。如果在通过RPC发送之前打印所有缓冲区,则会得到正确的输出(即打印整个文件)。但是,当我通过RPC发送它并打印服务器端的所有缓冲区时,最后一个节点打印不正确,就好像它没有正确传输一样 我已经用一个大的.txt文件(100,5kB)测试了我的代码,在这里它似乎确实有效。但是,对于.pdf文件(7,9kB),它不会 以下是我的(相关)代码:

在过去的几天里,我一直在为以下事情伤脑筋:我想通过SunRPC发送任何大小/类型的文件。在客户端,我将文件读入一个链表,每个节点包含一个大小为1024的缓冲区。如果在通过RPC发送之前打印所有缓冲区,则会得到正确的输出(即打印整个文件)。但是,当我通过RPC发送它并打印服务器端的所有缓冲区时,最后一个节点打印不正确,就好像它没有正确传输一样

我已经用一个大的.txt文件(100,5kB)测试了我的代码,在这里它似乎确实有效。但是,对于.pdf文件(7,9kB),它不会

以下是我的(相关)代码:

.x文件:

struct node {
    string buf<>;
    long bytes;
    struct node* next;
};

struct paper {
    string author<>;
    string title<>;
    struct node* file;
    struct paper* next;
};

typedef long add_out;

program PAPERSERVER_PROG {
    version PAPERSERVER_VERS {
        add_out ADDPAPER(paper) = 1;
    } = 1;
} = 0x20001234;
paperserver.c(此处输出错误)

编辑:

指定有关预期输出的更多信息。我希望通过服务器发送的文件的输出与调用
cat
时的输出完全相同。然而,输出的顺序似乎是错误的。最后一个缓冲区似乎被文件开头的某些内容覆盖。这是一个。pdf文件被使用。对于另一个.pdf文件,它可以工作;对于.txt文件,它可以工作;但是对于.jpg文件,它不能工作。当我得到输出的
md5sum
时,它会随着每次调用而改变。这让我觉得它打印的字节实际上并没有被我的程序初始化。此外,当我使用valgrind时,会出现以下错误(仅适用于无法正常工作的文件):


您正在使用
字符串buf
来包含文件数据。一个字符串将被第一个零字节终止,所以如果在数据中间有零字节(PDF文件可能会,但是文本文件不会),那么完整的数据就不会被写入。 (请注意,RPC无法知道
节点中有多少数据
——您碰巧将该数据放入
字节
,但RPC基础设施不知道……)

要解决此问题,您需要将
buf
改为
不透明

opaque buf<>;

当你说“输出错误”时,你能更具体一点吗?你期望的结果是什么?实际输出是什么?顺便问一下,你可能想看看
add_out* addpaper_1_svc(paper* in, struct svc_req* rqstp) { 
    static add_out out;
    struct node* file;
    long written;

    file = in->file;
    char* buf;

    while (file != NULL) {
        buf = calloc(BUF_SIZE + 1, 1);
        buf = memcpy(buf, file->buf, file->bytes);

        written = fwrite(buf, 1, file->bytes, stdout);

        if (ferror(stdout)) {
            perror("fwrite error");
            exit(2);
        } 

        file = file->next;
    }

    out = 0;

    return &out;
}
==2375== Invalid read of size 8
==2375==    at 0x4C2F790: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2375==    by 0x400D3E: addpaper_1_svc (paperserver.c:38)
==2375==    by 0x40128D: paperserver_prog_1 (paperserver_svc.c:76)
==2375==    by 0x4F626D0: svc_getreq_common (svc.c:534)
==2375==    by 0x4F6281D: svc_getreq_poll (svc.c:460)
==2375==    by 0x4F65BFE: svc_run (svc_run.c:96)
==2375==    by 0x401437: main (paperserver_svc.c:114)
==2375==  Address 0x527af48 is 392 bytes inside a block of size 394 alloc'd
==2375==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2375==    by 0x4F64D04: xdr_string (xdr.c:788)
==2375==    by 0x401487: xdr_node (paperserver_xdr.c:13)
==2375==    by 0x4F656B7: xdr_pointer (xdr_ref.c:84)
==2375==    by 0x40155C: xdr_paper (paperserver_xdr.c:31)
==2375==    by 0x401268: paperserver_prog_1 (paperserver_svc.c:72)
==2375==    by 0x4F626D0: svc_getreq_common (svc.c:534)
==2375==    by 0x4F6281D: svc_getreq_poll (svc.c:460)
==2375==    by 0x4F65BFE: svc_run (svc_run.c:96)
==2375==    by 0x401437: main (paperserver_svc.c:114)
==2375== 
==2375== Invalid read of size 8
==2375==    at 0x4C2F79E: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2375==    by 0x400D3E: addpaper_1_svc (paperserver.c:38)
==2375==    by 0x40128D: paperserver_prog_1 (paperserver_svc.c:76)
==2375==    by 0x4F626D0: svc_getreq_common (svc.c:534)
==2375==    by 0x4F6281D: svc_getreq_poll (svc.c:460)
==2375==    by 0x4F65BFE: svc_run (svc_run.c:96)
==2375==    by 0x401437: main (paperserver_svc.c:114)
==2375==  Address 0x527af50 is 6 bytes after a block of size 394 alloc'd
==2375==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2375==    by 0x4F64D04: xdr_string (xdr.c:788)
==2375==    by 0x401487: xdr_node (paperserver_xdr.c:13)
==2375==    by 0x4F656B7: xdr_pointer (xdr_ref.c:84)
==2375==    by 0x40155C: xdr_paper (paperserver_xdr.c:31)
==2375==    by 0x401268: paperserver_prog_1 (paperserver_svc.c:72)
==2375==    by 0x4F626D0: svc_getreq_common (svc.c:534)
==2375==    by 0x4F6281D: svc_getreq_poll (svc.c:460)
==2375==    by 0x4F65BFE: svc_run (svc_run.c:96)
==2375==    by 0x401437: main (paperserver_svc.c:114)  
opaque buf<>;
buf.buf_val = calloc(...);
buf.buf_len = num_bytes_read;