sockaddr – 打印所有sa_data保存的信息 – c ++

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

我想打印的方式,我可以理解(并请解释)sa_data 14个字节中的所有信息。

任何帮助?

谢谢!

一种可能性是使用inet_ntop ,它应该能够处理IPv4和IPv6地址。 它会产生一个地址可读的字符串。

在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的格式与使用的协议有所不同。

根据地址族: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中我没有找到。
 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流打印十六进制。

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

如果您使用的是IPv4,则正确的方法是将sockaddr指针转换为sockaddr_in * 。 在使用IPv4时,只有地址的前6个字节才有意义。 剩下的应该被忽略。

要获得并打印struct sockaddrsa_data member ,请参阅John在sockaddr结构中获取IPV4地址的答案