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

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

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

我看了一下这个问题, 如何将整数数组分解为一个字节数组(像素编码) ,但是无法理解它 – 如果这是我正在寻找的东西,请有人愚蠢一点吗?

跟进问题:

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

写的原型是:

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

注意:如果arrays来自动态内存(就像你编辑它一样),则不能在其上使用sizeof 。 在这种情况下,count将等于: sizeof(int) * element_count

编辑:

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

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

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

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

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

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

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

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

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

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

在客户端/服务器程序中进行序列化/反序列化function会更好。

无论何时想要发送数据,都要将数据序列化为字节缓冲区,并通过TCP发送字节数。

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

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

只要确保照顾到endianess和对齐的东西。

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

例如:

 char tcp[100]; tcp[0] = 0; tcp[1] = 0xA; tcp[2] = 0xB; tcp[3] = 0xC; . . // Send the character array write(sock, tcp, sizeof(tcp)); 

我认为你需要提出的是一个协议

假设你的整数数组是:

 100, 99, 98, 97 

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

 "100,99,98,97" 

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

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

//讽刺

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

 100999897 

🙂