简体   繁体   English

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

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

I'm lead to believe that write() can only send data buffers of byte (ie signed char), so how do I send an array of long integers using the C write() function in the sys/socket.h library?我相信write()只能发送字节的数据缓冲区(即有符号字符),那么如何使用 sys/socket.h 库中的 C write() function 发送长整数数组?

Obviously I can't just cast or convert long to char, as any numbers over 127 would be malformed.显然,我不能只将 long 转换为 char,因为任何超过 127 的数字都会出现格式错误。

I took a look at the question, how to decompose integer array to a byte array (pixel codings) , but couldn't understand it - please could someone dumb it down a little if this is what I'm looking for?我看了一下这个问题, 如何将 integer 数组分解为字节数组(像素编码) ,但无法理解 - 如果这是我要找的,请有人把它弄小一点吗?

Follow up question:跟进问题:

Why do I get weird results when reading an array of integers from a TCP socket? 为什么从 TCP 套接字读取整数数组时会得到奇怪的结果?

the prototype for write is: write 的原型是:

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

so while it writes in units of bytes, it can take a pointer of any type.因此,虽然它以字节为单位写入,但它可以采用任何类型的指针。 Passing an int* will be no problem at all.传递一个int*完全没有问题。

EDIT:编辑:

I would however, recomend that you also send the amount of integers you plan to send first so the reciever knows how much to read.但是,我建议您还发送您计划首先发送的整数数量,以便接收者知道要读取多少。 Something like this (error checking omitted for brevity):像这样的东西(为简洁起见省略了错误检查):

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

NOTE: if the array is from dynamic memory (like you malloc ed it), you cannot use sizeof on it.注意:如果数组来自动态 memory (就像你malloc编辑它),你不能使用sizeof In this case count would be equal to: sizeof(int) * element_count在这种情况下,计数将等于: sizeof(int) * element_count

EDIT:编辑:

As Brian Mitchell noted, you will likely need to be careful of endian issues as well.正如Brian Mitchell所指出的,您可能还需要注意字节序问题。 This is the case when sending any multibyte value (as in the count I recommended as well as each element of the array).发送任何多字节值时就是这种情况(如我推荐的计数以及数组的每个元素)。 This is done with the: htons / htonl and ntohs / ntohl functions.这是通过htons / htonlntohs / ntohl函数完成的。

Write can do what you want it to, but there's some things to be aware of: Write 可以做你想做的事,但是有一些事情需要注意:

1: You may get a partial write that's not on an int boundary, so you have to be prepared to handle that situation 1:您可能会收到不在 int 边界上的部分写入,因此您必须准备好处理这种情况

2: If the code needs to be portable, you should convert your array to a specific endianess, or encode the endianess in the message. 2:如果代码需要可移植,您应该将您的数组转换为特定的字节序,或者对消息中的字节序进行编码。

Yes, you can just cast a pointer to your buffer to a pointer to char , and call write() with that.是的,您可以将指向缓冲区的指针转换为指向char的指针,然后调用write() Casting a pointer to a different type in C doesn't affect the contents of the memory being pointed to -- all it does is indicate the programmer's intention that the contents of memory at that address be interpreted in a different way.将指针转换为 C 中的不同类型不会影响指向的 memory 的内容——它所做的只是表明程序员的意图,即该地址的 ZCD69B4957F06CD818D7BF3D61980E2 的内容以不同的方式解释。

Just make sure that you supply write() with the correct size in bytes of your array -- that would be the number of elements times sizeof (long) in your case.只需确保为write()提供数组的正确大小(以字节为单位) - 在您的情况下,这将是元素数乘以sizeof (long)

The simplest way to send a single int (assuming 4-byte ints) is:发送单个 int(假设 4 字节 int)的最简单方法是:

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

where htonl is a function that converts the int to network byte order .其中 htonl 是将 int 转换为网络字节顺序的 function 。 (Similarly,. when you read from the socket, the function ntohl can be used to convert back to host byte order.) (同样,当您从套接字读取时,function ntohl可用于转换回主机字节顺序。)

For an array of ints, you would first want to send the count of array members as an int (in network byte order), then send the int values.对于整数数组,您首先希望将数组成员的计数作为整数发送(按网络字节顺序),然后发送整数值。

Declare a character array.声明一个字符数组。 In each location of the array, store integer numbers, not characters.在数组的每个位置,存储 integer 数字,而不是字符。 Then you just send that.然后你就发送那个。

For example:例如:

char tcp[100];

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

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

It would be better to have serialize/de-serialize functionality in your client /server program.在您的客户端/服务器程序中具有序列化/反序列化功能会更好。

Whenever you want to send data, serialize the data into a byte buffer and send it over TCP with byte count.每当你想发送数据时,将数据序列化到一个字节缓冲区中,然后通过 TCP 发送它并带有字节数。

When receiving data, de-serialize the data from buffer to your own interpretation.接收数据时,将缓冲区中的数据反序列化为您自己的解释。

You can interpret byte buffer in any form as you like.您可以根据需要以任何形式解释字节缓冲区。 It can contain basic data type, objects etc.它可以包含基本数据类型、对象等。

Just make sure to take care of endianess and also alignment stuff.只要确保照顾好字节序以及 alignment 的东西。

I think what you need to come up with here is a protocol .我认为您需要在这里提出一个协议

Suppose your integer array is:假设您的 integer 数组是:

100, 99, 98, 97

Instead of writing the ints directly to the buffer, I would "serialize" the array by turning it into a string representation.我不会将整数直接写入缓冲区,而是通过将数组转换为字符串表示来“序列化”数组。 The string might be:字符串可能是:

"100,99,98,97"

That's what would be sent over the wire.这就是将通过电线发送的内容。 On the receiving end, you'd split the string by the commas and build the array back up.在接收端,您将用逗号分割字符串并备份数组。

This is more standardised, is human readable, and means people don't have to think about hi/lo byte orders and other silly things.这更加标准化,人类可读,并且意味着人们不必考虑高/低字节顺序和其他愚蠢的事情。

// Sarcasm // 讽刺

If you were working in .NET or Java, you'd probably encode it in XML, like this:如果您在 .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