sockaddr - 打印sa_data包含的所有信息 - c ++

时间:2010-12-16 17:36:04

标签: c++ linux sockets

在我的c ++应用程序中我使用sockaddr。我想看看sockaddr.sa_data [14]所持有的所有信息。现在我只是从sa_data打印ip [2] .sa_data [3] .sa_data [4] .sa_data [5]。

我想以一种我能理解(并且请解释)sa_data 14字节中的所有信息的方式进行打印。

任何帮助?

谢谢!

6 个答案:

答案 0 :(得分:5)

在sa_data成员中,对于Windows上的IPv4,我发现前两个字节保存了端口号,接下来的四个字节保存了IP地址。

例如,如果我解析地址228.0.0.1:9995,则sa_data成员是......

27 0b e4 00 00 01 00 00 00 00 00 00 00 00

这里,270b是前两个字节中的9995的十六进制值表示。接下来的四个字节是IP地址,其中0xe4是228,然后是两个零,然后是0x01或228 0 0 1.
最后八个字节未使用,这与上面的注释仅与前面使用的前六个字节相符。

请注意,sa_data的格式会因使用的协议而异。

答案 1 :(得分:2)

一种可能性是使用应该能够处理IPv4和IPv6地址的inet_ntop。它将生成一个带有地址的人类可读字符串。

答案 2 :(得分:1)

基于地址族:sa_family,改变了14个字节的sa_data的值(不同)。

  1. 如果地址族是AF_INET,前两个字节是端口号,接下来的4个字节是源IP地址。

  2. 如果地址族是PF_PACKET,前两个字节告诉以太网类型(0800 - > IP,0806 - > ARP等等)和接下来的4个字节(实际上是第一个字节)它足够了)它告诉源接口。如果值是:

    • 02 00 00 00 = eth0,
    • 03 00 00 00 = eth1,
    • 04 00 00 00 = eth2等......和 最后8个字节在AF_INET系列中未使用,但在PF_PACKET中我没有找到。

答案 3 :(得分:0)

std::copy( &sa_data[0], &sa_data[0]+sizeof(sa_data)/sizeof(sa_data[0]), 
             std::ostream_iterator<int>(std::cout, " "));

将每个元素打印为一个空格分隔的int。如果您不想要负值,也可以使用unsigned int,如果您愿意,可以使用iomanip流来打印十六进制。

答案 4 :(得分:0)

sockaddr中的信息取决于您正在使用的套接字系列和协议。

如果您使用的是IPv4,那么正确的做法是将sockaddr指针强制转换为sockaddr_in *。当您使用IPv4时,只有地址的前6个字节有意义。其余的应该被忽略。

答案 5 :(得分:0)

要获取并打印sa_data member的{​​{1}},请参阅约翰在Getting IPV4 address from a sockaddr structure的答案