UDP 源端口是什么时候设置的?

mar*_*and 2 c sockets udp

我正在编写一个非常小的 C UDP 客户端。我知道当您将数据发送到服务器时,会选择一个随机端口作为源端口。我也知道你可以使用 bind 来指定你想要响应的端口。

但是不知道什么时候端口是随机选择的?例如,我想依靠发件人地址来跟踪用户。它目前只有在客户端没有关闭时才有效,端口仍然相同,那么简单的 memcmp 就足以检测到相同的客户端。

这个小代码将使用相同的源端口,直到它退出:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>

int main(void)
{
    int s, error, ch;
    struct addrinfo hints, *res;

    memset(&hints, 0, sizeof (struct addrinfo));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_DGRAM;

    if ((error = getaddrinfo("localhost", "9988", &hints, &res)))
            errx(1, "%s", gai_strerror(error));

    if ((s = socket(res->ai_family, res->ai_socktype, 0)) < 0)
            err(1, "socket");

    while ((ch = fgetc(stdin)) != EOF)
            sendto(s, &ch, 1, 0, res->ai_addr, res->ai_addrlen);
}
Run Code Online (Sandbox Code Playgroud)

并运行类似: dmesg | ./client 将使用相同的地址,直到程序退出。但是,当您再次运行它时,端口就不同了。

那么选择端口的就是socket函数吗?还是系统?确定端口在客户端生命周期内仍然相同吗?

Som*_*ude 5

如果套接字未明确绑定,则操作系统将在您发送第一个数据包时绑定它(使用随机端口)。只要套接字打开,此绑定就会处于活动状态,一旦关闭,套接字(当然)就未绑定。

并且由于 UDP 套接字的无连接特性,“服务器”(如果正确完成)不应无限期地保留所有发送给它的“客户端”的地址。相反,它应该使用在recvfrom调用中收到的源地址,并将其用于回复。为不仅仅是简单的请求/响应存储源地址的唯一原因是,如果您在 UDP 之上有一个更高级的协议,并且您自己的“连接”处理。