我正在尝试将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时,我会'转换为非转换器类型请求'。
我尝试了很多组合,根本不明白我哪里出错了。
答案 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_addr
是struct sockaddr_storage *
,您可以使用其地址 - 这是一个struct sockaddr_storage **
,并试图将其投射出去。那不行。
我不知道peer_addr
来自哪里,但是
struct sockaddr_storage
(我认为不需要在某处指向struct sockaddr_storage
)(struct sockaddr *) peer_addr
- &
- 传递给getnameinfo()
。另一点:getnameinfo()
的第二个参数应该是您输入的地址结构的“实际”大小。