getaddrinfo()获取域名的地址
域名系统(Domain Name System, DNS)是一本巨大的通讯录。计算机向网络发送数据包时需要在地址一栏填写数字形式的IP地址,而DNS可以把www.oreilly.com这样的域名转化为IP地址。
创建域名套接字
通常情况下,应该让客户端代码用DNS来创建套接字,这样用户就不需要自己去查找IP地址。为了使用DNS,需要以另一种方式构建客户端套接字:
getaddrinfo()
会在堆上创建一种叫名字资源的新数据结构。给定域名和端口号,就可以得到名字资源。名字资源把计算机需要的IP地址隐藏了起来,大型网站通常有好几个IP地址,代码会从中挑选一个。随后便可以用名字资源创建套接字了。
最后,你可以连接远程套接字。因为名字资源在堆上创建,所以要用一个叫freeaddrinfo()
的函数清除它。
一旦把套接字连接到远程端口,就可以用recv()
和send()
函数读写数据,你在服务器中已用过它们。你现在掌握的知识已经够写一个网络客户端了……
代码冰箱贴
网络客户端的代码如下,它将从维基百科下载某个页面的内容,然后在屏幕上显示。网址将通过参数传给程序。仔细思考一下,如果网络服务器使用了HTTP协议,你需要向它发送什么数据?
代码冰箱贴解答
网络客户端的代码如下,它将从维基百科下载某个页面的内容,然后在屏幕上显示。网址将通过参数传给程序。仔细思考一下,如果网络服务器使用了HTTP协议,你需要向它发送什么数据?
试驾
编译代码,运行网络客户端,它成功地从维基百科下载到了网页:
成功了!
客户端从命令行读取了网页的名字,然后连接到维基百科下载了网页。因为网页名要建立文件路径,所以必须用下划线(_)替换其中的空格。
滑野雪
为什么不让代码自动把空格替换成下划线?如何替换字符生成网址?详情请见:
这里没有蠢问题
问:我应该用IP地址还是域名创建套接字?
答:最好用域名。一来域名比较好记,二来服务器有时会改变IP地址,但域名一般不会变。
问:那我还用知道怎么连接IP地址吗?
答:需要。如果你要连接的服务器没有在域名系统中注册,比如家庭网络中的计算机,你就需要知道如何用IP连接。
问:我可以把IP地址作为
getaddrinfo()
的参数吗?答:可以。但如果你要连接IP地址,可以用第一版创建客户端套接字的代码,它更简单。
要点
协议是一段结构化对话。
服务器连接本地端口。
客户端连接远程端口。
客户端和服务器使用套接字通信。
用
send()
向套接字写数据。用
recv()
从套接字读数据。HTTP是一种网络协议。