我对getaddrinfo()的行为有疑问,这似乎取决于如何指定服务参数。将服务指定为名称会导致getaddrinfo()使用getservbyname()来查询/ etc / services数据库,但是在数字上明确指定服务不会导致此类查询,这会导致结果出现差异。
例如,指定service =“5672”(amqp的端口),返回协议IPPROTO_TCP,IPPROTO_UDP和IPPROTO_IP的addrinfo结构列表,同时指定service =“amqp”,返回addrinfo结构列表协议IPPROTO_TCP,IPPROTO_UDP和IPPROTO_SCTP。
为什么在数据指定服务时getaddrinfo()不查询/ etc / services数据库?谢谢你的帮助。
更新:
事实证明,这就是getaddrinfo()如何设计来处理服务参数。如果你知道端口号,那很好。如果您只知道服务名称,getaddrinfo()将为您查找端口号。
对我来说真正的问题是,即使SCTP安装在我的系统上(Ubuntu 16.04),getaddrinfo()也不会返回带有IPPROTO_SCTP的addrinfo结构。查看getaddrinfo()的源代码,看起来它返回了它在构建时所知道的所有协议的addrinfo结构而不是当时被调用。
我想我可能需要重建glibc才能获得支持SCTP的getaddrinfo()版本。任何人都可以确认或纠正我的理解吗?
答案 0 :(得分:0)
显然有很多代码假设protocol = 0而type = SOCK_STREAM 意味着 TCP。如果getaddrinfo()返回带有IPPROTO_SCTP的addrinfo结构,则此代码会中断。折衷的解决方案(至少对于FreeBSD和Linux),一直是让getaddrinfo()只返回协议= 0和类型= SOCK_STREAM的IPPROTO_TCP addrinfo结构。任何想要getaddrinfo()返回带有IPPROTO_SCTP的addrinfo结构的人都应该在提示中指定ai_protocol = IPPROTO_SCTP。这仅在将服务arg指定为数字时适用;指定为名称的服务将导致getaddrinfo()查询/ etc / services数据库,结果中指定的协议将基于在那里找到的协议。