我有一个小型客户端/服务器应用程序,用于发送/接收UDP发现数据包。收到UDP数据包时,我想显示源IP。客户端/服务器代码基于Beej的UDP示例:https://beej.us/guide/bgnet/html/multi/clientserver.html
当我编译为64位时,IP会按预期显示,但是当我编译为32位(-m32选项)时,它根本没有得到正确的值。
代码snippit:
// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
...
printf("listener: waiting to recvfrom...\n");
addr_len = sizeof their_addr;
if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0,
(struct sockaddr *)their_addr, &addr_len)) == -1) {
perror("recvfrom");
exit(1);
}
printf("listener: got packet from %s\n",
inet_ntop(their_addr->sa_family,
get_in_addr((struct sockaddr *)their_addr),
s, sizeof s));
printf("Sockaddr: ");
for (i=0; i<sizeof(struct sockaddr_in); i++)
printf("%x ", ((char *)their_addr)[i]);
printf("\n");
编译为64位时更正输出:
listener: waiting to recvfrom...
listener: got packet from 192.168.20.6
Sockaddr: 2 0 ffffff80 19 ffffffc0 ffffffa8 14 6 64 2e 40 0 0 0 0 0
使用-m32:
编译时输出错误 listener: waiting to recvfrom...
listener: got packet from 168.32.140.255
Sockaddr: 2 0 ffffff80 19 ffffffa8 20 ffffff8c ffffffff 50 ffffffdd 7d fffffff7 4 0 0 0
我真的不明白为什么在编译32位时使用get_in_addr或inet_ntop会出现问题?
答案 0 :(得分:3)
addr_len
应设置为地址结构的大小,而不是指针的大小(它发生在64位模式下,因为指针在该模式下是两倍大)。所以它应该是:
addr_len = sizeof *their_addr;
顺便提一下,their_addr
如何初始化?必须有一个真实的结构指向。
答案 1 :(得分:2)
除了错误之外,这是一种处理IP地址的方法。您应该使用带有getnameinfo
标志的NI_NUMERICHOST
来获得可呈现的地址形式。那么你不必关心它是v4还是v6,甚至是v7或v8。
答案 2 :(得分:0)
get_in_addr
不是标准函数。很可能你的实现错了。显示代码。