从 recvfrom 收到错误地址:为什么?
Bad address received from recvfrom: why?
我正在编写一个函数,该函数应该执行一些操作,然后 return(使用其参数)正在与之交互的设备的地址(即使用 sendto
) recvfrom
函数内部。
下面是我调用函数的方式,之前实例化了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);
// ...
}
现在,即使发送设备的 IP 地址是 192.168.1.251
,我也会得到以下输出:
Received '0packetx' from '0.0.0.0'.
接收缓冲区格式正确,但地址明显错误。为什么?跟函数外定义地址变量有关系吗?
编辑
如果在 cliaddr
的 memset
之后我还添加了那 3 行:
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
)。
如果您用有效的 sizeof 数据填充 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))
我正在编写一个函数,该函数应该执行一些操作,然后 return(使用其参数)正在与之交互的设备的地址(即使用 sendto
) recvfrom
函数内部。
下面是我调用函数的方式,之前实例化了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);
// ...
}
现在,即使发送设备的 IP 地址是 192.168.1.251
,我也会得到以下输出:
Received '0packetx' from '0.0.0.0'.
接收缓冲区格式正确,但地址明显错误。为什么?跟函数外定义地址变量有关系吗?
编辑
如果在 cliaddr
的 memset
之后我还添加了那 3 行:
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
)。
如果您用有效的 sizeof 数据填充 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))