在我的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的值被改变(不同)。
如果地址族是AF_INET,则前两个字节是端口号,接下来的4个字节将是源IP地址。
如果地址族是PF_PACKET,则前两个字节将告诉以太网类型(枯燥0800-> IP,0806-> ARP等),接下来的4个字节(实际上第一个字节就足够了)告诉源接口。 如果值是:
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 sockaddr
的sa_data member
,请参阅John在sockaddr结构中获取IPV4地址的答案