gpt4 book ai didi

c - UDP套接字的源端口和目标端口?

转载 作者:IT王子 更新时间:2023-10-29 00:57:45 28 4
gpt4 key购买 nike

我正在通过编写一个向指定服务器发送 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));
}

这工作正常,因为查询已成功发送,并收到回复。但是,通过使用 Wireshark 嗅探流量,我可以看到消息:Destination unreachable (Port unreachable)

我发现我可以通过在 sendto() 之前调用 bind() 来避免这种情况:

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));
}

现在 Destination unreachable (Port unreachable) 消息消失了,但应用程序必须以 root 权限运行,因为它将绑定(bind)到端口 53。

是否可以修改代码以便改用随机的非特权源端口?

问题已解决

问题的发生是因为一个愚蠢的错误。我只是简单地注释掉了 recvfrom()。当我在测试应用程序时嗅探流量时,我可以看到响应和错误到达我的计算机,并在应用程序接收时错误地将其混淆。因为我不知道自己到底在做什么,所以我开始乱搞 bind() 等,然后就开始了这种雪崩式的失败。

为简洁起见,我没有发布所有代码,但如果这样做的话,问题可能会立即得到解决。

最佳答案

您可以绑定(bind)到端口 0,让操作系统随机选择一个可用的端口(就像 INADDR_ANY 为 0)。参见 https://stackoverflow.com/a/1077305/3543692

此外,绑定(bind)到端口 53 毫无意义。 53端口是DNS服务器的端口,不是DNS客户端的端口。想一想如果你电脑上的所有DNS客户端都使用53作为DNS客户端端口,那么只能同时对一台服务器进行一个DNS请求。通常,所有客户端(包括 TCP/UDP)都使用操作系统分配的随机未使用端口。

关于c - UDP套接字的源端口和目标端口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29711247/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com