5

假设有“cat”、“bat”、“rat”3个字符串,我需要将它们组合成一个字符串,然后通过socket编程将它们发送到另一台不同Endianess的计算机上。

所以,如果另一台机器是大端,我会将字符串打包为:
memcpy (base, "cat", 3)
memcpy (base+3, "bat", 3)
memcpy (base+6, "rat", 3)

如果另一台机器是小端,我会将字符串打包为:
memcpy (base, "rat", 3)
memcpy (base+3, "bat", 3)
memcpy (base+6, "cat", 3)

我的方法正确吗?

其次,它们实际上会以相反的顺序在另一台机器上接收吗?我的意思是,当另一台机器的软件开始从“基础”字符串中提取字符串时,它实际上是否会以相反的顺序排列——比如老鼠、蝙蝠、猫?

4

2 回答 2

6

当您将包含两个字节的内存缓冲区转储0x02 0x00到套接字中时,0x02首先发送,然后0x00发送。当接收者从套接字读取时,0x02将首先到达,并将存储在缓冲区的开头。0x00第二个到达,并在 之后立即存储0x02。所以,在你做了之后send(sock, &buffer, 2),接收者做recv(sock, &buffer, 2)了,你的和接收者的buffers 的内容是相同的——在字节级别上。

但是现在出现了一个解释问题。是的,你有两个字节,0x02 0x00, 在内存中,但那又怎样?他们的意思是什么?哦,他们的意思是范围内的整数0..65535,你说?但是有两种方法可以存储这样的数字。第一种是在第一个字节中存储更多有效位,因此512 = 10'00000000存储为0x02 0x00. 第二种是在第一个字节中存储较低的有效位,因此512存储为0x00 0x02, 并且是存储, not0x02 0x00的一种方式。2512

所以,重要的教训是:当你发送一些数据时,你必须确保接收者会像你一样解释它们。跨越多个字节的整数可以有不同的解释,因此您必须以某种方式就发送它们的确切方式达成一致。

现在,回到字符串。C 中的字符串是概念和表示级别的字节序列——整数不是这样!当你使用整数时,我敢打赌你不会很在意它们被表示为一堆字节,而实际的表示不是由 C 指定的。你的编译器可以以它想要的任何方式存储整数。然而,字符串按一定顺序排列的字节序列,这在 C 中是固定的。你有第一个字符,第二个字符,依此类推。所以只有一种解释02 00为字符串的方法:它是一个包含第一个字符0x02和第二个字符的 2 个字符的字符串0x00。没有混淆是可能的。

PS 当然,当你开始考虑字符串不是字节序列,而是字符序列时,解释的问题又出现了:哪个字节意味着什么字符?但那是另一回事了。

编辑:在你对另一个答案的评论中,你说你“必须为另一台机器做准备,以知道我发送的实际上是一个整数而不是一个字符串”。是的。这是与其他机器交换数据的主要问题:你发送的和他们看到的只是一个字节序列。现在这个交换的所有参与者都必须以相同的方式解释这个字节序列,否则他们会感到困惑。如果您的意思是发送数字512并通过发送字节来执行此操作0x02 0x00,那么另一方会更好地理解0x02 0x00您的意思是512而不是2,或者说START OF TEXT。或者,当你发送0x31 0x32 0x33 0x00你的意思是"123",而不是825373440,或者31323300

不过,原始问题的答案是:“如果我发送"catbatrat",发件人会看到什么?” 是:“发件人将看到"catbatrat",独立于字节序”。

于 2013-05-24T07:38:31.970 回答
3

字节顺序在字节级别没有区别,因此对于 8 位字符的字符串或数据只是字节流的任何其他内容,您无需担心它。

对于元素大于一个字节的任何内容,例如 2 个或更多字节整数、浮点等,那么您确实需要担心字节顺序,或者使用基于文本的格式进行数据交换。

于 2013-05-24T07:15:03.960 回答