什么时候设置UDP源端口?

时间:2021-04-02 23:58:12

I'm writing a very small C UDP client. I know that a random port is chosen as source port when you send data to the server. I also know that you can use bind to specify yourself the port you want a response.

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

However, I don't know when is the port randomly chosen? For example, I would like to rely on the sender address to keep track of users. It currently works only if the client does not shutdown, the port is still the same then a simple memcmp is enough to detect the same client.

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

This small code will use the same source port until it exits:

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

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

And running something like : dmesg | ./client will use the same address until the program exits. However, when you run it again, the port is different.

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

So is it the socket function that choose a port? Or the system? Is it sure that the port will still be the same during the client lifetime?

那么选择端口的套接字功能呢?还是系统?是否确保端口在客户端生命周期内仍然相同?

1 个解决方案

#1


3  

If the socket is not explicitly bound, then the OS will bind it (with a random port) when you send the first packet. This binding will be active as long as the socket is open, once it's closed the socket is (of course) unbound.

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

And due to the connectionless nature of UDP sockets, the "server" (if done correctly) should not keep the address of all "clients" that send to it indefinitely. Instead it should use the source address as received in the recvfrom call, and use that for a reply. The only reason to store the source address for more than just a simple request/response, is if you have a more advanced protocol on top of UDP with your own "connection" handling.

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

#1


3  

If the socket is not explicitly bound, then the OS will bind it (with a random port) when you send the first packet. This binding will be active as long as the socket is open, once it's closed the socket is (of course) unbound.

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

And due to the connectionless nature of UDP sockets, the "server" (if done correctly) should not keep the address of all "clients" that send to it indefinitely. Instead it should use the source address as received in the recvfrom call, and use that for a reply. The only reason to store the source address for more than just a simple request/response, is if you have a more advanced protocol on top of UDP with your own "connection" handling.

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