Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将sockaddr\u存储转换为inet\u ntop的sockaddr\u输入_C_Sockets - Fatal编程技术网

将sockaddr\u存储转换为inet\u ntop的sockaddr\u输入

将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,

我试图将一个sockaddr_存储转换为一个sockaddr_输入,这样我就可以打印出数据报包的源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时得到“转换为请求的非缩放器类型”

我已经尝试了很多组合,只是不明白我错在哪里

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);