繁体   English   中英

如何在 C 中的 TCP 上发送整数数组?

[英]How do I send an array of integers over TCP in C?

我相信write()只能发送字节的数据缓冲区(即有符号字符),那么如何使用 sys/socket.h 库中的 C write() function 发送长整数数组?

显然,我不能只将 long 转换为 char,因为任何超过 127 的数字都会出现格式错误。

我看了一下这个问题, 如何将 integer 数组分解为字节数组(像素编码) ,但无法理解 - 如果这是我要找的,请有人把它弄小一点吗?

跟进问题:

为什么从 TCP 套接字读取整数数组时会得到奇怪的结果?

write 的原型是:

ssize_t write(int fd, const void *buf, size_t count);

因此,虽然它以字节为单位写入,但它可以采用任何类型的指针。 传递一个int*完全没有问题。

编辑:

但是,我建议您还发送您计划首先发送的整数数量,以便接收者知道要读取多少。 像这样的东西(为简洁起见省略了错误检查):

int x[10] = { ... };
int count = 10;
write(sock, &count, sizeof(count));
write(sock, x, sizeof(x));

注意:如果数组来自动态 memory (就像你malloc编辑它),你不能使用sizeof 在这种情况下,计数将等于: sizeof(int) * element_count

编辑:

正如Brian Mitchell所指出的,您可能还需要注意字节序问题。 发送任何多字节值时就是这种情况(如我推荐的计数以及数组的每个元素)。 这是通过htons / htonlntohs / ntohl函数完成的。

Write 可以做你想做的事,但是有一些事情需要注意:

1:您可能会收到不在 int 边界上的部分写入,因此您必须准备好处理这种情况

2:如果代码需要可移植,您应该将您的数组转换为特定的字节序,或者对消息中的字节序进行编码。

是的,您可以将指向缓冲区的指针转换为指向char的指针,然后调用write() 将指针转换为 C 中的不同类型不会影响指向的 memory 的内容——它所做的只是表明程序员的意图,即该地址的 ZCD69B4957F06CD818D7BF3D61980E2 的内容以不同的方式解释。

只需确保为write()提供数组的正确大小(以字节为单位) - 在您的情况下,这将是元素数乘以sizeof (long)

发送单个 int(假设 4 字节 int)的最简单方法是:

int tmp = htonl(myInt);
write(socket, &tmp, 4);

其中 htonl 是将 int 转换为网络字节顺序的 function 。 (同样,当您从套接字读取时,function ntohl可用于转换回主机字节顺序。)

对于整数数组,您首先希望将数组成员的计数作为整数发送(按网络字节顺序),然后发送整数值。

声明一个字符数组。 在数组的每个位置,存储 integer 数字,而不是字符。 然后你就发送那个。

例如:

char tcp[100];

tcp[0] = 0;
tcp[1] = 0xA;
tcp[2] = 0xB;
tcp[3] = 0xC;
.
.

// Send the character array
write(sock, tcp, sizeof(tcp));

在您的客户端/服务器程序中具有序列化/反序列化功能会更好。

每当你想发送数据时,将数据序列化到一个字节缓冲区中,然后通过 TCP 发送它并带有字节数。

接收数据时,将缓冲区中的数据反序列化为您自己的解释。

您可以根据需要以任何形式解释字节缓冲区。 它可以包含基本数据类型、对象等。

只要确保照顾好字节序以及 alignment 的东西。

我认为您需要在这里提出一个协议

假设您的 integer 数组是:

100, 99, 98, 97

我不会将整数直接写入缓冲区,而是通过将数组转换为字符串表示来“序列化”数组。 字符串可能是:

"100,99,98,97"

这就是将通过电线发送的内容。 在接收端,您将用逗号分割字符串并备份数组。

这更加标准化,人类可读,并且意味着人们不必考虑高/低字节顺序和其他愚蠢的事情。

// 讽刺

如果您在 .NET 或 Java 中工作,您可能会将其编码为 XML,如下所示:

<ArrayOfInt><Int>100</Int><Int>99</Int><Int>98</Int><Int>97</Int></ArrayOfInt>

:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM