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

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()等等,这种雪崩的失败开始了.

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

cyb*_*ibo 2

您可以绑定到端口 0,让操作系统随机选择一个可用的端口(就像 INADDR_ANY 为 0 一样)。请参阅/sf/answers/75411381/

此外,绑定到端口 53 没有任何意义。53端口是DNS服务器的端口,不是DNS客户端的端口。想象一下,如果您计算机上的所有 DNS 客户端都使用 53 作为 DNS 客户端端口,那么只能同时处理一个对服务器的 DNS 请求。通常,所有客户端(TCP/UDP)都使用操作系统分配的随机未使用端口。

  • @user4793972:您应该传递带有 INADDR_ANY 和端口 0 的 sockaddr_in 进行绑定,并将带有 8.8.8.8 和端口 53 的 sockaddr_in 传递给 sendto。 (2认同)