将sockaddr_storage转换为sockaddr_in for inet_ntop

Bab*_*ack 3 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);
Run Code Online (Sandbox Code Playgroud)

当我尝试将结构转换为sockaddr_in时,我要么"无法转换为指针",要么当我删除dereferance时,我会'转换为非转换器类型'.

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

Mar*_*n R 9

inet_ntop(peer_addr->ss_family, &(((struct sockaddr_in *)peer_addr)->sin_addr), ipbuff, INET_ADDRSTRLEN);
Run Code Online (Sandbox Code Playgroud)

应该管用.但请考虑使用getnameinfo(),这是更现代的界面:

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

适用于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);
Run Code Online (Sandbox Code Playgroud)

或者,使用inet_ntop():

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