2010-03-25 48 views
2

我正在与套接字编程打架,我遇到了一个问题,我不知道如何以便携方式解决问题。 这个任务很简单:我需要通过网络发送16字节的数组,然后在客户端应用程序中接收并解析它。我知道,有像htonl,htons和uint16和uint32这样的函数。但是,我应该如何处理比这更大的数据块呢?通过套接字发送任意长度的数组。 Endianness

谢谢。

回答

3

你说一个16字节的数组。这并没有什么帮助。字节顺序只对大于一个字节的事物很重要。

如果这是真的原始字节然后只是给他们,你会收到他们一样的

如果这是真的,你要

struct msg 
{ 
    int foo; 
    int bar; 
..... 

发送它,那么你需要通过缓冲工作一个struct拉取你想要的值。

当您发送您必须组建一个包成一个标准的顺序

int off = 0; 
*(int*)&buff[off] = htonl(foo); 
off += sizeof(int); 
*(int*)&buff[off] = htonl(bar); 
... 

当您收到

int foo = ntohl((int)buff[off]); 
off += sizeof(int); 
int bar = ntohl((int)buff[off]); 
.... 

编辑:我看你要发送的IPv6地址,他们总是处于网络字节顺序 - 所以你可以直接对它进行流式处理。

1

htonshtonl等用于处理大于一个字节的单个数据项(例如int)。其中每个字节用作单个数据项本身的字节数组(例如,字符串)根本不需要在主机和网络字节顺序之间进行转换。

+0

我有点困惑。我的机器有little-endian字节顺序,我试图通过网络发送ipv6地址作为一个字节数组。据我所知,我们必须恢复字节(第16个成为第一个),传输它们,并在客户端(如果它也是小端)恢复字节。我对吗? – 2010-03-25 20:47:21

+0

IPv6地址应该按照big-endian顺序作为数组发送。您应该(通常情况下)能够将其视为基本上不透明的数据 - 例如,您将收到16个字节并将它们完全按照您收到的那样复制到sockaddr_in6中。IP堆栈可能会决定在内部交换它们,但您应该从外部看到的所有内容都将按网络顺序进行交换。有一天,如果你有一台128位的机器,并想加载一个并将其作为一个数字操作,那么你不得不担心一个'ntohlll'和'htonlll'(或任何使用的名字)。 – 2010-03-25 21:34:08

3

Endianness是多字节变量(如16位和32位整数)的属性。它与高位或低位字节先行有关。如果客户端应用程序将数组作为单个字节进行处理,则不必担心字节顺序,因为字节中的位顺序相同。

1

字节本身不再有字节序,因为计算机发送的任何单字节在不同的接收计算机中都具有相同的值。现在,字节序仅与多字节数据类型(如整数)相关。

在你的具体情况下,它归结为知道接收器将用你的16字节做什么。如果它将数组中的16个条目中的每一个都视为离散的单字节值,那么您可以发送它们而不用担心endiannes。另一方面,如果接收方将16字节数组视为4个32位整数,那么您需要在发送之前通过hton()运行每个整数。

这有帮助吗?