我使用wireshark查看DHCP数据包结构。现在我创建了一个DHCPDISCOVER请求并将其存储在'message'中。然后我在网络上播放它。
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("socket");
exit(1);
}
setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST, &on,sizeof(on));
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR, &on,sizeof(on));
bzero(&cliaddr, sizeof(cliaddr));
cliaddr.sin_family = AF_INET;
cliaddr.sin_addr.s_addr = htonl(INADDR_ANY);
cliaddr.sin_port = htons(68);
if (bind(sockfd, (struct sockaddr *) &cliaddr, sizeof(cliaddr)) < 0) {
perror("bind");
exit(1);
}
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("255.255.255.255");
addr.sin_port = htons(67);
cnt = sendto(sockfd, message, sizeof(message), 0,(struct sockaddr *) &addr, sizeof(addr));
if (cnt < 0) {
perror("sendto");
exit(1);
}
addrlen = sizeof(servaddr);
cnt = recvfrom(sockfd, reply, sizeof(reply), 0,(struct sockaddr *) &servaddr, &addrlen);
if (cnt < 0) {
perror("recvfrom");
exit(1);
}
printf("\nReply Received\n");
我运行此程序并分析使用wireshark发送和接收的数据包。我看到端口67上发送了DHCPDISCOVER数据包,并且在wireshark窗口的端口68上收到了DHCPOffer数据包。我的客户端发送数据包正常,但没有收到此数据包,它会在recvfrom呼叫时阻止。出了什么问题?
答案 0 :(得分:1)
您需要在发送数据包请求之前将接收信息发送出去,否则响应可能会在您准备好接收之前回复。
此外,响应是否广播?如果没有,并且您当前没有为您的计算机分配IP地址,那么您将在收到它时遇到一些问题,因为您的主机将按IP地址过滤收到的数据包,但不会知道响应是针对它的(即使链接层地址匹配),所以它也不会提供它。
但我的猜测是这是第一个问题。您必须使用线程或进行非阻塞接收,否则您的接收将被阻止,因此您永远不会到处发送请求。
答案 1 :(得分:0)
我不同意上面的答案.. recvfrom应该能够同时收到这两个数据包。 这里的问题在于,端口号在1000的范围内。通常,这些数据包由linux内核(iptables)过滤而不发送到。用户申请。 https://bugzilla.redhat.com/show_bug.cgi?id=983672