如何使用 getaddrinfo_a 与 glibc 进行异步解析
一个经常被忽视的功能,不需要外部库,但基本上没有任何文档。
An often overlooked function that requires no external library, but basically has no documentation whatsoever.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
更新 (2010-10-11):Linux 手册页现在有 getaddrinfo_a 的文档,您可以在这里找到它:http://www.kernel.org/doc/man-pages/online/pages/man3/getaddrinfo_a.3.html
作为免责声明,我应该补充一点,我对 C 很陌生,但不完全是新手,因此可能存在错误或不好的编码实践,请纠正我(我的语法也很糟糕)。
我个人并不知道它,直到我发现 Adam Langley 的这篇文章,我将给出一些代码片段来说明它的用法,并澄清一些第一次使用时可能不太清楚的事情。 使用此功能的好处是,您可以轻松获取可在 socket()、listen() 和其他函数中使用的数据,如果做得正确,您将不必担心关于 ipv4/v6 也可以。
因此,首先从基础知识开始,如上面的链接所示(您需要链接 libanl (-lanl)):
下面是函数原型:
介绍 gaicb 结构体像这样:
如果您熟悉 getaddrinfo,那么这些字段与它们的对应关系如下:
节点是 ar_name 字段,service 是端口,hints 参数对应于 ar_request 成员,结果存储在其余部分中。< br>
现在,您可以指定如何通过 sigevent 结构获得通知:
所以基本上,如果您想查找主机名,请将 ar_name 设置为主机并设置其他一切都为NULL,如果您想连接到主机,请设置 ar_name 和 ar_service ,如果您想创建服务器,请指定 ar_service 和 ar_result 字段。 您当然可以根据自己的喜好自定义 ar_request 成员,请查看 man getaddrinfo 了解更多信息。
如果您有一个带有 select/poll/epoll/kqueue 的事件循环,您可能需要使用 signalfd 为方便起见。 Signalfd 创建一个文件描述符,您可以在其中使用通常的事件轮询机制,如下所示:
您当然也可以使用简单的信号处理程序来完成此工作,请查看 man sigaction 了解更多信息。
UPDATE (2010-10-11): The linux man-pages now have documentation of the getaddrinfo_a, you can find it here: http://www.kernel.org/doc/man-pages/online/pages/man3/getaddrinfo_a.3.html
As a disclaimer I should add that I'm quite new to C but not exactly a newbie, so there might be bugs, or bad coding practices, please do correct me (and my grammar sucks too).
I personally didn't know about it until I came upon this post by Adam Langley, I shall give a few code snippets to illustrate the usage of it and clarify some things that might not be that clear on first use. The benefits of using this is that you get back data readily usable in socket(), listen() and other functions, and if done right you won't have to worry about ipv4/v6 either.
So to start off with the basics, as taken from the link above (you will need to link against libanl (-lanl)) :
Here is the function prototype:
A gaicb struct looks like this:
If you're familiar with getaddrinfo, then these fields correspond to them like so:
The node is the ar_name field, service is the port, the hints argument corresponds to the ar_request member and the result is stored in the rest.
Now you specify how you want to be notified through the sigevent structure:
So basically if you want to look up a hostname you set ar_name to the host and set everything else to NULL, if you want to connect to a host you set ar_name and ar_service , and if you want to create a server you specify ar_service and the ar_result field. You can of course customize the ar_request member to your hearts content, look at man getaddrinfo for more info.
If you have an event loop with select/poll/epoll/kqueue you might want to use signalfd for convenience. Signalfd creates a file descriptor on which you can use the usuall event polling mechanisms like so:
You can of course use a simple signal handler for this job too, look at man sigaction for more info.