我正在关注关于NP的Beej指南。
我做了一些修改,并试图通过getaddrinfo()获取我的服务器程序的IP。
(原文可在此处找到https://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#simpleserver )
以下是我更改/添加的部分。
if ((rv = getaddrinfo(NULL, "0", &hints, &servinfo)) != 0) { //0 for random port? fprintf(stderr, "getaddrinfo: %sn", gai_strerror(rv)); return 1; } //... some code emitted ... //freeaddrinfo(servinfo); //I still need it! printf("ip: %snport: %dn", inet_ntop(AF_INET, &((struct sockaddr_in *)p->ai_addr)->sin_addr, ip4, INET_ADDRSTRLEN), ntohs(((struct sockaddr_in *)p->ai_addr)->sin_port) );
问题是我得到了结果
ip: 0.0.0.0 port: 0
Q1:我从几个网站上读到,为端口设置“0”告诉操作系统你想要下一个可用端口,而不是实际为0.这是真的吗?
Q2:我还读过gethostbyname(gethostname(…))可以给你机器的ip,但Beej说这些被getaddrinfo()取代了。 那么,我应该使用getaddrinfo吗? 还是gethostbyname?
问题3:还有什么我做错了吗?
Q1:我从几个网站上读到,为端口设置“0”告诉操作系统你想要下一个可用端口,而不是实际为0.这是真的吗?
是的,但只有在使用bind()
将地址附加到真正的套接字之后。 此时,使用getsockname()
从套接字获取绑定地址; 港口将是其中的一部分。
Q2:我还读过gethostbyname(gethostname(…))可以给你机器的ip,但Beej说这些被getaddrinfo()取代了。 那么,我应该使用getaddrinfo吗? 还是gethostbyname?
使用getaddrinfo()
; 它完成gethostbyname()
所做的一切以及更多,并且界面糟糕得多。 (例如,它通常是线程安全的。)
问题3:还有什么我做错了吗?
服务器的IP地址没有明确定义的概念。 由于多个网卡(服务器比桌面系统更常见),服务器可能有很多,而外界认识的服务器可能不是其中之一(感谢NAT防火墙)。 有时,您可以在客户端连接之前确切地知道消息的来源 – 最常见的选择是知道客户端将在localhost
– 这是您在bind()
期间设置的信息的一部分,但这种情况很少见。 通过使用getpeername()
您可以在连接发生后找到客户端的地址,但NAT可能仍会使function无用。 这些地址通常在部署期间在应用程序的配置文件中设置。
如果您只需要用于记录目的的信息,请继续。 但要注意将其用于其他任何事情,因为它实际上并没有告诉你那么多。
它正在回归你所期望的那样。
来自man getaddrinfo
:
如果在hints.ai_flags中指定了AI_PASSIVE标志,并且node为NULL,则返回的套接字地址将适合于绑定(2)将接受(2)连接的套接字。 返回的套接字地址将包含“通配符地址”(IPv4地址为INADDR_ANY,IPv6地址为IN6ADDR_ANY_INIT)。 通配符地址由打算接受任何主机网络地址上的连接的应用程序(通常是服务器)使用。 如果node不为NULL,则忽略AI_PASSIVE标志。
您链接的代码将hints.ai_flags
设置为AI_PASSIVE
并且您为节点传递NULL
。 通配符地址是0.0.0.0
。 按规定工作。 绑定到该地址意味着您绑定到计算机上的每个IP地址。
至于港口……你指的是"0"
,这正是你要回来的。 您需要将它想要设置的实际端口设置为您链接的示例代码。
以上就是c/c++开发分享从getaddrinfo()获取服务器ip 0.0.0.0:0相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/560399.html