我正在编写一个应该执行某些操作的函数,然后返回(使用其参数)与之交互的设备的地址(即使用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
)。
答案 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电话之前把它放好。