我正在使用C中的POSIX套接字将一个树莓派的大小的整数数组发送到另一个树莓派。我正在从一个pi编写一个大小为131072的整数数组,write命令的返回值显示所有131072值都已被写入。 ret = write(socket, &array, sizeof(array))
使用相同的接收方法ret = read(socket, &array, sizeof(array))
表示未读取所有已发送的值,而是正确读取的值的数量也不是恒定的,而是在10000到20000之间变化。
我试图在循环中使用read函数,在每次循环迭代中我都读取整数
for(int i =0; i<131072; i++){
ret = read(socket, &value, sizeof(value));
data[i] = value;}
我能够毫无错误地接收所有值。
答案 0 :(得分:0)
基础协议(可能是TCP和IP)将数据拆分为数据包,这些数据包可能作为单独的数据块到达接收应用程序。从理论上讲,read()
可能会单独接收每个字节(即,当调用2000次时,每次返回1)。您的应用程序需要能够使用它。
答案 1 :(得分:0)
您可能需要使用与此类似的代码:
multi-rw.h
#ifndef JLSS_ID_MULTI_RW_H
#define JLSS_ID_MULTI_RW_H
#include <sys/types.h>
extern ssize_t multi_read(int fd, char *buffer, size_t nbytes);
extern ssize_t multi_write(int fd, const char *buffer, size_t nbytes);
#endif
multi-rw.c
不幸的是,测试代码块必须位于活动函数之前,但这是必需的(并且测试代码是必需的-至少,我觉得它非常有用并且令人放心)。我想它可以进入一个单独的头文件(multi-rw-test.h
或其附近),该文件将有条件地包括在内;最好用SO表示,否则就是另一个需要担心的文件。
#include "multi-rw.h"
#include <unistd.h>
#ifdef TEST
#ifndef MAX_WRITE_SIZE
#define MAX_WRITE_SIZE 64
#endif
#ifndef MAX_READ_SIZE
#define MAX_READ_SIZE 64
#endif
static inline size_t min_size(size_t x, size_t y) { return (x < y) ? x : y; }
static inline ssize_t pseudo_read(int fd, char *buffer, size_t nbytes)
{
return read(fd, buffer, min_size(MAX_READ_SIZE, nbytes));
}
static inline ssize_t pseudo_write(int fd, const char *buffer, size_t nbytes)
{
return write(fd, buffer, min_size(MAX_READ_SIZE, nbytes));
}
#undef read
#undef write
#define read(fd, buffer, nbytes) pseudo_read(fd, buffer, nbytes)
#define write(fd, buffer, nbytes) pseudo_write(fd, buffer, nbytes)
#endif
ssize_t multi_read(int fd, char *buffer, size_t nbytes)
{
ssize_t nb = 0;
size_t nleft = nbytes;
ssize_t tbytes = 0;
while (nleft > 0 && (nb = read(fd, buffer, nleft)) > 0)
{
tbytes += nb;
buffer += nb;
nleft -= nb;
}
if (tbytes == 0)
tbytes = nb;
return tbytes;
}
ssize_t multi_write(int fd, const char *buffer, size_t nbytes)
{
ssize_t nb = 0;
size_t nleft = nbytes;
ssize_t tbytes = 0;
while (nleft > 0 && (nb = write(fd, buffer, nleft)) > 0)
{
tbytes += nb;
buffer += nb;
nleft -= nb;
}
if (tbytes == 0)
tbytes = nb;
return tbytes;
}
#ifdef TEST
#include "stderr.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
if (argc != 0)
err_setarg0(argv[0]);
char buffer[4096];
ssize_t ibytes;
while ((ibytes = multi_read(0, buffer, sizeof(buffer))) > 0)
{
ssize_t obytes;
if ((obytes = multi_write(1, buffer, ibytes)) != ibytes)
err_syserr("failed to write %lld bytes - only wrote %lld bytes\n",
(long long)ibytes, (long long)obytes);
}
if (ibytes < 0)
err_syserr("I/O error reading standard input: ");
return 0;
}
#endif
通过测试工具,您可以测试从标准输入读取的代码并写入标准输出。您可以通过(例如)编译命令行选项-DMAX_WRITE_SIZE=132
和-DMAX_READ_SIZE=103
配置读取的数据量。您需要在小于(a)4096字节和(b)小于最大读写大小的文件上以及在大于4096字节的文件上进行测试。如果您有足够的动力,则可以升级pseudo_read()
和pseudo_write()
函数以准随机地生成错误,以查看代码如何处理此类错误。