首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何查找本地/临时端口号?

如何查找本地/临时端口号?
EN

Stack Overflow用户
提问于 2018-11-09 05:07:20
回答 3查看 504关注 0票数 1

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

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

代码语言:javascript
复制
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()来设置本地端口,但我的问题是,当操作系统为我选择本地端口时会发生什么。

EN

回答 3

Stack Overflow用户

发布于 2018-11-09 05:12:19

您需要getsockname函数:

代码语言:javascript
复制
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套接字中均可用。

票数 0
EN

Stack Overflow用户

发布于 2018-11-09 15:26:10

sendto()状态的MSDN文档:

注意:如果打开了一个套接字,进行了一个隐式setsockopt调用,然后进行了一个隐式sendto调用,则Windows会执行一个隐式 socket 函数调用

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

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

票数 0
EN

Stack Overflow用户

发布于 2018-11-09 15:29:28

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

至于何时由操作系统分配临时端口,从ip(7) Linux manual page

...在以下情况下,会将临时端口分配给套接字:

当在先前未绑定的流套接字上调用bind(2);

  • listen(2)时,在先前未绑定的套接字上调用bound;

  • connect(2)时,将套接字地址中的端口号指定为0。在先前未绑定的数据报套接字上调用bound;

  • sendto(2)时,将
  • 指定为0。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53216146

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档