如何在C中通过TCP发送整数数组?

时间:2009-03-23 04:29:28

标签: c sockets tcp

我认为write()只能发送byte的数据缓冲区(即signed char),所以如何使用sys中的C write()函数发送长整数数组/socket.h库?

显然,我不能只是强制转换或转换为char,因为任何超过127的数字都会格式不正确。

我看了一下这个问题,how to decompose integer array to a byte array (pixel codings),但无法理解 - 如果这是我正在寻找的东西,请有人愚蠢一点吗?

跟进问题:

Why do I get weird results when reading an array of integers from a TCP socket?

7 个答案:

答案 0 :(得分:15)

写的原型是:

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));

注意:如果阵列来自动态内存(如malloc编辑),则无法在其上使用sizeof。在这种情况下,count将等于:sizeof(int) * element_count

修改

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

答案 1 :(得分:6)

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

1:你可能得到一个不在int边界上的部分写入,所以你必须准备好处理这种情况

2:如果代码需要是可移植的,您应该将数组转换为特定的endianess,或者在消息中编码endianess。

答案 2 :(得分:2)

是的,您只需将指向缓冲区的指针转换为指向char的指针,然后使用该指针调用write()。在C中转换指向不同类型的指针不会影响所指向的内存的内容 - 它所做的只是表明程序员打算以不同的方式解释该地址的内存内容。

只需确保为write()提供数组的正确大小(以字节为单位) - 这将是您案例中sizeof (long)次元素的数量。

答案 3 :(得分:2)

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

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

其中htonl是一个将int转换为network byte order的函数。 (类似地,当您从套接字读取时,函数ntohl可用于转换回主机字节顺序。)

对于一个int数组,首先要将数组成员的数量作为int(以网络字节顺序)发送,然后发送int值。

答案 4 :(得分:1)

最好在客户端/服务器程序中使用序列化/反序列化功能。

每当您想发送数据时,将数据序列化为字节缓冲区并通过TCP发送字节数。

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

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

请确保照顾到结尾和对齐的内容。

答案 5 :(得分:1)

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

例如:

char tcp[100];

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

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

答案 6 :(得分:0)

我认为您需要提出的是协议

假设您的整数数组是:

100, 99, 98, 97

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

"100,99,98,97"

这就是通过电线发送的内容。在接收端,您将用逗号分隔字符串并重新构建数组。

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

// Sarcasm

如果您使用的是.NET或Java,您可能需要用XML编码,如下所示:

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

:)