将sockaddr\u存储转换为inet\u ntop的sockaddr\u输入
我试图将一个sockaddr_存储转换为一个sockaddr_输入,这样我就可以打印出数据报包的源ip地址, 我似乎无法正确地确定演员阵容将sockaddr\u存储转换为inet\u ntop的sockaddr\u输入,c,sockets,C,Sockets,我试图将一个sockaddr_存储转换为一个sockaddr_输入,这样我就可以打印出数据报包的源ip地址, 我似乎无法正确地确定演员阵容 struct sockaddr_storage peer_addr; getnameinfo((struct sockaddr *) &peer_add peer_addrlen, hostbuff, sizeof(hostbuff), NULL,
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时得到“转换为请求的非缩放器类型”
我已经尝试了很多组合,只是不明白我错在哪里
inet_ntop(peer_addr->ss_family, &(((struct sockaddr_in *)peer_addr)->sin_addr), ipbuff, INET_ADDRSTRLEN);
应该有用。但是请考虑使用<代码> GETNAMEIOFER()<代码>,这是比较现代的。
接口:
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\u ntop()
:
你把东西混在一起了
getnameinfo()
确实将struct-sockaddr*
作为其第一个参数,但您在此处尝试执行的操作无效:peer\u-addr
是一个struct-sockaddr\u存储*
,您可以获取它的地址,即struct-sockaddr\u存储**
,然后尝试强制转换它。那不行
我不知道你的同级地址来自哪里,但是
- 或者它应该是一个
struct sockaddr\u存储
(我认为不需要在某处有指向struct sockaddr\u存储
的指针)
- 或者它实际上是一个指针,您应该将
(struct sockaddr*)peer\u addr
(不带&
)传递到getnameinfo()
另一点:getnameinfo()
的第二个参数应该是您正在输入的地址结构的“真实”大小。我以为getnameinfo()返回了地址的主机名?@Babbleshack:请参阅“man getnameinfo”,了解NI_numericost标志:以数字形式返回地址,就像调用inet_ntop(3)一样,而不是主机名。可移植的方法不是使用peer\u addr->ss\u family
(至少在我的系统上还不知道),而是使用分配的结构的实际大小。@Babbleshack:我可以问一下你为什么“不接受”这个答案吗?它不再工作了吗当然,glglgl是正确的,使用实际的sockaddr长度(例如recvfrom()返回的长度)是更方便的方法,但这不应该使我的答案完全错误。-如果你改变了问题,就会让人困惑。最初,peer_addr是指向struct sockaddr_存储的指针,因此我的回答假设是这样的。@MartinR谢谢你的回答反映了我的工作代码。我已经重新接受了你的答案。当我尝试这样做时,我得到了一个编译错误,当我使用我的原始代码时,我的程序按预期工作。这是否意味着我有“未定义的行为”@Babbleshack我不知道这意味着什么,因为我不知道你会遇到哪个编译错误。但是你很可能会得到UB,因为演员阵容可能会隐藏和隐藏问题。当我从sockaddr中删除dereferance时,我会得到“转换为非缩放类型”错误
char ipbuff[INET_ADDRSTRLEN];
inet_ntop(peer_addr.ss_family, &(((struct sockaddr_in *)&peer_addr)->sin_addr), ipbuff, INET_ADDRSTRLEN);
struct sockaddr_storage * peer_addr;
getnameinfo((struct sockaddr *) &peer_add
peer_addrlen,
hostbuff, sizeof(hostbuff),
NULL, 0, NI_NAMEREQD);