将sockaddr_storage转换为sockaddr_in for inet_ntop

时间:2013-11-21 19:42:52

标签: c sockets

我正在尝试将sockaddr_storage转换为sockadd_in,以便我可以打印出数据报包的源IP地址, 我似乎无法使演员阵容正确,

struct sockaddr_storage  peer_addr;


getnameinfo((struct sockaddr *) &peer_add
                peer_addrlen,
                hostbuff, sizeof(hostbuff),
                NULL, 0, NI_NAMEREQD);


inet_ntop(AF_INET, (((struct sockaddr_in *)peer_addr).sin_addr), ipbuff, INET_ADDRSTRLEN);

当我尝试将结构强制转换为sockaddr_in时,我要么“无法转换为指针”,要么当我删除dereferance时,我会'转换为非转换器类型请求'。

我尝试了很多组合,根本不明白我哪里出错了。

2 个答案:

答案 0 :(得分:9)

inet_ntop(peer_addr->ss_family, &(((struct sockaddr_in *)peer_addr)->sin_addr), ipbuff, INET_ADDRSTRLEN);

应该有效。但是考虑使用getnameinfo()代替,这是更现代的 接口:

char host[NI_MAXHOST];
getnameinfo((struct sockaddr *)peer_addr, peer_addr->ss_len, host, sizeof(host), NULL, 0, NI_NUMERICHOST);

适用于IPv4和IPv6地址。


根据问题中更改的类型

更新:这是一个完整的示例 应该在没有警告的情况下进行编译:

int socket = ...;

struct sockaddr_storage peer_addr;
socklen_t peer_addrlen;
char host[NI_MAXHOST];

ssize_t amount;
char buffer[1000];
amount = recvfrom(socket, buffer, sizeof(buffer), 0, (struct sockaddr *)&peer_addr, &peer_addrlen);
getnameinfo((struct sockaddr *)&peer_addr, peer_addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST);

或者,使用inet_ntop()

char ipbuff[INET_ADDRSTRLEN];
inet_ntop(peer_addr.ss_family, &(((struct sockaddr_in *)&peer_addr)->sin_addr), ipbuff, INET_ADDRSTRLEN);

答案 1 :(得分:2)

struct sockaddr_storage  *  peer_addr;


getnameinfo((struct sockaddr *) &peer_add
                peer_addrlen,
                hostbuff, sizeof(hostbuff),
                NULL, 0, NI_NAMEREQD);

这里你要混合东西。

getnameinfo()确实需要struct sockaddr*作为其第一个参数,但您尝试在此处执行的操作无效:peer_addrstruct sockaddr_storage *,您可以使用其地址 - 这是一个struct sockaddr_storage **,并试图将其投射出去。那不行。

我不知道peer_addr来自哪里,但是

  • 它应该是struct sockaddr_storage(我认为不需要在某处指向struct sockaddr_storage
  • 或者它确实是一个指针,您应该将(struct sockaddr *) peer_addr - & - 传递给getnameinfo()

另一点:getnameinfo()的第二个参数应该是您输入的地址结构的“实际”大小。