从recvfrom收到的错误地址:为什么?

时间:2018-01-22 18:27:38

标签: c sockets pointers recvfrom

我正在编写一个应该执行某些操作的函数,然后返回(使用其参数)与之交互的设备的地址(即使用sendto){{1}在函数内部。

以下是我如何调用该函数,之前实例化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

现在,即使发送设备的IP地址为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); // ... } ,我也会得到以下输出:

192.168.1.251

接收到的缓冲区格式正确,但地址显然是错误的。为什么?它是否与函数外的地址变量的定义有关?

修改

如果在Received '0packetx' from '0.0.0.0'. memset我添加了这3行:

cliaddr

我得到随机行为。有时我会收到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)。

2 个答案:

答案 0 :(得分:2)

你将错误的长度传递给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))

答案 1 :(得分:-2)

如果您使用有效的sizeof数据填充plen,它应该有效。

*plen = sizeof(struct sockaddr_in);

你可以在recvfrom电话之前把它放好。