getaddrinfo()获取域名的地址

域名系统(Domain Name System, DNS)是一本巨大的通讯录。计算机向网络发送数据包时需要在地址一栏填写数字形式的IP地址,而DNS可以把www.oreilly.com这样的域名转化为IP地址。

getaddrinfo()获取域名的地址 - 图1

创建域名套接字

通常情况下,应该让客户端代码用DNS来创建套接字,这样用户就不需要自己去查找IP地址。为了使用DNS,需要以另一种方式构建客户端套接字:

getaddrinfo()获取域名的地址 - 图2

getaddrinfo()会在堆上创建一种叫名字资源的新数据结构。给定域名和端口号,就可以得到名字资源。名字资源把计算机需要的IP地址隐藏了起来,大型网站通常有好几个IP地址,代码会从中挑选一个。随后便可以用名字资源创建套接字了。

getaddrinfo()获取域名的地址 - 图3

最后,你可以连接远程套接字。因为名字资源在堆上创建,所以要用一个叫freeaddrinfo()的函数清除它。

getaddrinfo()获取域名的地址 - 图4

一旦把套接字连接到远程端口,就可以用recv()send()函数读写数据,你在服务器中已用过它们。你现在掌握的知识已经够写一个网络客户端了……

getaddrinfo()获取域名的地址 - 图5代码冰箱贴

网络客户端的代码如下,它将从维基百科下载某个页面的内容,然后在屏幕上显示。网址将通过参数传给程序。仔细思考一下,如果网络服务器使用了HTTP协议,你需要向它发送什么数据?

getaddrinfo()获取域名的地址 - 图6

getaddrinfo()获取域名的地址 - 图7代码冰箱贴解答

网络客户端的代码如下,它将从维基百科下载某个页面的内容,然后在屏幕上显示。网址将通过参数传给程序。仔细思考一下,如果网络服务器使用了HTTP协议,你需要向它发送什么数据?

getaddrinfo()获取域名的地址 - 图8

getaddrinfo()获取域名的地址 - 图9试驾

编译代码,运行网络客户端,它成功地从维基百科下载到了网页:

getaddrinfo()获取域名的地址 - 图10

成功了

客户端从命令行读取了网页的名字,然后连接到维基百科下载了网页。因为网页名要建立文件路径,所以必须用下划线(_)替换其中的空格。

getaddrinfo()获取域名的地址 - 图11滑野雪

为什么不让代码自动把空格替换成下划线?如何替换字符生成网址?详情请见:

http://www.w3schools.com/tags/ref_urlencode.asp

 

这里没有蠢问题

问:我应该用IP地址还是域名创建套接字?

:最好用域名。一来域名比较好记,二来服务器有时会改变IP地址,但域名一般不会变。

问:那我还用知道怎么连接IP地址吗?

:需要。如果你要连接的服务器没有在域名系统中注册,比如家庭网络中的计算机,你就需要知道如何用IP连接。

问:我可以把IP地址作为getaddrinfo()的参数吗?

:可以。但如果你要连接IP地址,可以用第一版创建客户端套接字的代码,它更简单。

 

getaddrinfo()获取域名的地址 - 图12要点

  • 协议是一段结构化对话。

  • 服务器连接本地端口。

  • 客户端连接远程端口。

  • 客户端和服务器使用套接字通信。

  • send()向套接字写数据。

  • recv()从套接字读数据。

  • HTTP是一种网络协议。