c-如何查找本地/星历表端口号



我有一个UDP客户端程序,它使用Berkley套接字和Winsock(取决于平台(。

基本上,它使用getaddrinfo(),然后使用socket(),然后再使用sendto()sendto()getaddrinfo()返回的地址信息。我的代码如下:

struct addrinfo hint;
memset(&hint, 0, sizeof(hint));
hint.ai_socktype = SOCK_DGRAM;
struct addrinfo *address;
getaddrinfo("127.0.0.1", "9999", &hint, &address);
SOCKET s = socket(address->ai_family, address->ai_socktype, address->ai_protocol);
sendto(s, "test", 4, 0, address->ai_addr, address->ai_addrlen);

我的问题是,本地/临时端口号是什么时候设置的?是否设置为调用sendto()?如果我将更多数据发送到不同的服务器,sendto()是否重复使用相同的临时端口号?如何获取临时端口号(以独立于协议的方式(?我知道知道这可能没有用,NAT无论如何都可以改变它,但我只是想了解这一切是如何更好地工作的。

我也知道我可以使用bind()来设置本地端口,但我的问题是当操作系统为我选择本地端口时会发生什么。

您想要getsockname函数:

struct sockaddr_storage ss;
socklen_t len;
len = sizeof(ss);
if (getsockname(s, (struct sockaddr *)&ss, &len) == 0) {
// print contents of ss
}

它用套接字绑定到的地址和端口填充给定的sockaddr

此函数在winsock和Berkely套接字中都可用。

MSDN的sendto()文档说明:

注意:如果打开套接字,进行setsockopt调用,然后进行sendto调用,Windows套接字将执行隐式bind函数调用

如果套接字未绑定,系统会将唯一值分配给本地关联,然后将套接字标记为绑定。如果套接字已连接,则可以使用getsockname函数来确定与套接字关联的本地IP地址和端口。

如果套接字未连接,getsockname函数可用于确定与套接字关联的本地端口号,但返回的IP地址设置为给定协议的通配符地址(例如,对于IPv4,INADDR_ANY或"0.0.0.0",对于IPv6,IN6ADDR_ANY_INIT或"::"(。

可以bind到端口zero(0(,这将导致操作系统找到一个打开的临时端口,您可以使用getsockname发现该端口,或者甚至在尝试发送任何内容之前返回EADDRINUSE


对于,当操作系统分配临时端口时,从ip(7(Linux手册页面:

[…]一个临时端口被分配给下面的套接字情况:

  • 当调用CCD_ 23;

  • 在先前未绑定的流套接字上调用CCD_ 24;

  • 在以前未调用的套接字上调用了connect(2)跳跃

  • 在先前未绑定的数据报套接字上调用sendto(2)

相关内容

  • 没有找到相关文章

最新更新