如何使用recvfrom获取AF_INET6套接字的地址

时间:2013-08-19 06:46:00

标签: c++ c linux sockets ip-address

recvfrom要求第5个参数是指向sockaddr结构的指针,第6个参数是指向socklen_t的指针。

man recvfrom (3)说:

  

如果地址的实际长度大于   提供的sockaddr结构,存储的地址应被截断。

我不知道如何检索AF_INET6地址系列的发送套接字地址,因为sockaddr_in6的大小大于sockaddr因此会被{{1}截断}。

我是否认为recvfrom无法检索大于recvfrom的地址?

即使我将sizeof(sockaddr)的实例定义为sockaddr_in6并将其传递给sockaddr*并将其传递给recvfrom,该功能也无法知道空间可用于存储地址?

2 个答案:

答案 0 :(得分:7)

您将sockaddr_in6(类型转换)的指针和sockaddr_in6结构的大小作为参数传递:

struct sockaddr_in6 in6;
socklen_t len6 = sizeof(in6);

recvfrom(sock, buf, buflen, (struct sockaddr *) &in6, &len6);

由于您将正确的长度传递给函数,它将起作用。

答案 1 :(得分:7)

将其强制转换为sockaddr*

此外,人们经常使用sockaddr_storage,因为它是defined

  

标题应定义sockaddr_storage结构。   该结构应为:

     
      
  • 足够大以容纳所有支持的协议特定地址结构
  •   
  • 在适当的边界对齐,以便指向它的指针可以作为指向协议特定地址结构的指针并用于   访问这些结构的字段而没有对齐问题
  •   

通过这种方式,您可以将它用于多种协议,因此您不会受到IPv6或IPv4的限制。

所以你可以做到

struct sockaddr_storage addr;
socklen_t sa_len = sizeof(addr);

recvfrom (sock, buffer, sizeof (buffer), (struct sockaddr*) &addr, &sa_len);

如果你需要知道sockaddr的kinf是什么,你可以检查每个sockaddr结构中存在的强制sa_family_t ss_family字段。

您可能也对此link或此one感兴趣。