Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.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
接收到来自recvfrom的错误地址:为什么?_C_Sockets_Pointers_Recvfrom - Fatal编程技术网

接收到来自recvfrom的错误地址:为什么?

接收到来自recvfrom的错误地址:为什么?,c,sockets,pointers,recvfrom,C,Sockets,Pointers,Recvfrom,我正在编写一个函数,该函数应该执行一些操作,然后返回(使用其参数)与函数中的recvfrom进行交互的设备的地址(即使用sendto) 下面是我调用函数的方式,在前面实例化了cliaddr struct sockaddr_in cliaddr; memset((void *) &cliaddr, 0, sizeof(cliaddr)); rcv_string(sockfd, &return_string, &cliaddr); // Here I'll need to u

我正在编写一个函数,该函数应该执行一些操作,然后返回(使用其参数)与函数中的
recvfrom
进行交互的设备的地址(即使用
sendto

下面是我调用函数的方式,在前面实例化了
cliaddr

struct sockaddr_in cliaddr;
memset((void *) &cliaddr, 0, sizeof(cliaddr));
rcv_string(sockfd, &return_string, &cliaddr);
// Here I'll need to use cliaddr, that's why I need it outside too
以下是该功能的实现:

int rcv_string(int sockfd, char **return_string, struct sockaddr_in *sndaddr) {
    // ...
    char buff[PACKETSZ + 2];
    memset(&buff, 0, sizeof(buff)); // Clean buffer
    socklen_t *plen = malloc(sizeof(struct sockaddr *));
    if ((recvfrom(sockfd, buff, sizeof(buff), 0, (struct sockaddr *) sndaddr, plen)) < 0) {
            perror("recvfrom");
            return -1;
    }
    char *snd_ip = malloc(INET_ADDRSTRLEN * sizeof(char));
    if (inet_ntop(AF_INET, &((*sndaddr).sin_addr.s_addr), snd_ip, INET_ADDRSTRLEN * sizeof(char)) == NULL) {
            perror("inet_ntop");
            return -1;
    }
    printf("Received '%s' from '%s'.\n", buff, snd_ip);
    // ...
}
接收到的缓冲区格式正确,但地址明显错误。为什么?它是否与函数外部地址变量的定义有关

编辑 如果在
cliaddr
memset
之后,我还添加了这三行:

cliaddr.sin_family = AF_INET;
cliaddr.sin_addr.s_addr = htonl(INADDR_ANY);
cliaddr.sin_port = htons(SERV_PORT);

我有一种随机行为。有时我会得到
0.0.0.0
,有时是
127.0.0.1
,有时是正确的地址(
192.168.1.251
)。

如果用有效的大小数据填充plen,它应该会起作用

*plen = sizeof(struct sockaddr_in);

您可以将其放在recvfrom调用之前。

您将错误的长度传递给recvfrom

  socklen_t *plen = malloc(sizeof(struct sockaddr *));
    if ((recvfrom(sockfd, buff, sizeof(buff), 0, (struct sockaddr *) sndaddr, plen))
你为什么要去malloc是个谜,但你需要

socklen_t *plen = malloc(sizeof(socklen_t));
*plen = sizeof(struct sockaddr_in );
更简单的是

      socklen_t plen = sizeof(struct sockaddr_in);
   if ((recvfrom(sockfd, buff, sizeof(buff), 0, (struct sockaddr *) sndaddr, &plen))

次要:
(*sndaddr).sin_addr
=
sndaddr->sin_addr
仅仅因为您有接受指针参数的函数,并不意味着您需要使用动态内存分配。通常你不会。相反,当可以创建指向适当类型的普通对象的指针时,请使用运算符的地址(
&
)。或者有时使用数组比较合适。谢谢@EugeneSh。和@JohnBollinger,谢谢你的评论。从现在起,我会尽力听从你的暗示。你知道我为什么得到
0.0.0.0
?这真让我困惑(你是对的,谢谢你的回答:我修复了它,但是错误的ip问题当然没有解决。我很惊讶这个问题没有得到更多的关注。我已经坚持了好几天了,读了这篇文章后,我意识到我用作
recvfrom
示例的所有3个源都是错误的!它们都没有初始化实际长度关于中的一个
sockaddr\u!狡猾的是,如果不这样做,大约50%的时间仍然有效,有效载荷似乎总是完好无损地到达。
      socklen_t plen = sizeof(struct sockaddr_in);
   if ((recvfrom(sockfd, buff, sizeof(buff), 0, (struct sockaddr *) sndaddr, &plen))