use*_*972 6 c sockets linux networking udp
我正在通过编写一个将DNS查询发送到指定服务器的小应用程序来学习C. 以下是网络代码的示例:
int send_query()
{
int sockfd;
struct sockaddr_in server;
if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
perror("cannot create socket\n");
}
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(53);
inet_pton(AF_INET, "8.8.8.8", &(server.sin_addr));
sendto(sockfd, const void *buffer, size_t length, 0, (struct sockaddr *) &server, sizeof(server));
}
Run Code Online (Sandbox Code Playgroud)
这可以正常工作,因为查询已成功发送,并收到回复.但是,通过使用Wireshark嗅探流量,我可以看到以下消息:Destination unreachable (Port unreachable).
我发现我可以通过调用避免此bind()之前sendto():
int send_query()
{
int sockfd;
struct sockaddr_in server;
if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
perror("cannot create socket\n");
}
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(53);
inet_pton(AF_INET, "8.8.8.8", &(server.sin_addr));
if(bind(sockfd, (struct sockaddr *) &server, sizeof(server)) < 0) {
perror("bind failed\n");
}
sendto(sockfd, const void *buffer, size_t length, 0, (struct sockaddr *) &server, sizeof(server));
}
Run Code Online (Sandbox Code Playgroud)
现在Destination unreachable (Port unreachable)消息消失了,但是应用程序必须以root权限运行,因为它将绑定到端口53.
是否可以修改代码,以便使用随机的非特权源端口?
问题解决了
由于一个愚蠢的错误,问题出现了.我只是评论了一下recvfrom().当我在测试应用程序时嗅探流量时,我可以看到计算机上的响应和错误,并且在应用程序正在接收时错误地混淆了这一点.因为我不知道我到底在做什么,所以我开始捣乱bind()等等,这种雪崩的失败开始了.
为简洁起见,我没有发布所有代码,但如果这样做了,问题可能会立即得到解决.
您可以绑定到端口 0,让操作系统随机选择一个可用的端口(就像 INADDR_ANY 为 0 一样)。请参阅/sf/answers/75411381/
此外,绑定到端口 53 没有任何意义。53端口是DNS服务器的端口,不是DNS客户端的端口。想象一下,如果您计算机上的所有 DNS 客户端都使用 53 作为 DNS 客户端端口,那么只能同时处理一个对服务器的 DNS 请求。通常,所有客户端(TCP/UDP)都使用操作系统分配的随机未使用端口。