我通过套接字发送一个C结构,但无法正确,总是错过一些字节

bxs*_*shi 1 c sockets linux

更新:我添加了一个while来获取剩余数据,问题解决了.谢谢你们.

while(res != rcvread->size + 4) {/* do not get full data */
    tmp = recv(connfd, (void *)rcvread + res, rcvread->size + 4 - res, 0);
    if(tmp == -1)
        printf("error:%s\n",(char *)strerror(errno));
    res+=tmp;
}
Run Code Online (Sandbox Code Playgroud)

我想mfsio通过套接字发送一个结构,返回值write是37772,但是当我从其他程序得到它时,返回值read是32768,这真的很奇怪.

这个结构的定义在这里

struct mfsio{
    size_t size;
    char buf[];
};
Run Code Online (Sandbox Code Playgroud)

发送代码在这里

struct mfsio *sndread;
sndread = malloc(sizeof(struct mfsio) + rcvcmd->size);
res = pread(fd, &(sndread->buf), rcvcmd->size, rcvcmd->offset);
sndread->size = res;
res = write(connfd, sndread, sizeof(struct mfsio) + res);
Run Code Online (Sandbox Code Playgroud)

接收代码在这里

struct mfsio *rcvread;
rcvread = malloc(sizeof(struct mfsio) + size);
res = 0;    
res = read(connfd, rcvread, sizeof(struct mfsio) + size);
Run Code Online (Sandbox Code Playgroud)

size等于rcvcmd->size,并且res pread为32678,res write为32772.但res read为32678.

怎么会发生这样的事情?我在这里做错了吗?

如果没有输入write,该read函数将只等待一些数据并挂在那里

如果我使用循环来避免这样的问题,我怎么能最终获得整个数据结构,我的意思是如果我做循环读取,我将从套接字中获取剩余字节,但是我如何组合这些剪辑?

Fra*_* IV 8

您需要在循环中进行读取和写入,直到读取/写入所有预期的数据.对于读取,您必须读取,直到它返回0,表示没有其他可用.或-1表示错误.

您最近的问题是您正在使用指针算法与结构指针:

tmp = recv(connfd, rcvread + res, rcvread->size + 4 - res, 0);
Run Code Online (Sandbox Code Playgroud)

在C中,当您进行指针运算时,您不使用字节,但是您正在使用对象的大小(例如rvcread).您应该定义一个char *读取位置的字节位置,然后在读取数据时更新它.