通过解析器向DNS服务器发出查询
浏览器将URL通过系统调用交由DNS解析器进行处理,(DNS解析器包含在操作系统的socket库)解析完成后将IP返回到某个内存地址。
Socket库是用于调用网络功能的程序组件集合
和浏览器一样,解析器也不具备网络数据收发功能,,解析器调用协议栈,然后通过网卡将消息发送给DNS服务器。
来自客户端的消息包含一下三种信息:
- 域名
- Class
- 记录类型 (A表示域名对应的是IP地址,MX表示域名对应的是邮件服务器)
DNS服务器会从域名与IP地址的对照表中查找相应的记录,并返回IP地址。
总结来说,收发数据的操作分为若干阶段:
- 创建套接字(创建套接字阶段)
- 将管道连接到服务器端的套接字上(连接阶段)
- 收发数据(通信阶段)
- 断开管道并删除套接字(断开阶段)
数据收发操作概览
查询IP地址只需要调用Socket库中的一个组件,而收发数据操作需要按照指定的顺序调用多个组件。
向操作系统内部的协议栈发出委托时,需要按照指定的顺序来调用Socket库中的程序组件。
建立管道的关键在于管道两端的数据出入口,这些出入口称为套接字。
客户端与服务器端收发操作的情形:
套接字完成后协议栈会返回一个描述符,应用程序将收到的描述符放在内存中。描述符用来识别不同的套接字。(一个浏览器可能会打开好多网页,每个网页对应一个套接字)
描述符:应用程序通过“描述符”识别套接字
IP和端口号:客户端和服务器之间用来识别对方套接字的机制
连接阶段:把管道连接上去
套接字创建好后,通过调用connect
完成连接。需要指定描述符,服务器IP和端口号着三个参数。
通信阶段
只要将数据传入套接字,数据就会被发送到对方的套接字中。应用程序无法直接控制套接字,需要通过Socket库委托协议栈来完成。
管道建立连接后,便会调用write方法(需指定描述符和发送的数据),将数据发送到指定服务器。
接下来,服务器执行接收操作,解析数据,返回响应信息。
当消息返回后,客户端执行接收,通过调用Socket库中的read程序组件委托协议栈来完成,调用read方法需要指定用于存放接收到的响应消息的内存地址,这一内存地址被称为接收缓冲区。接收缓冲区是一块位于应用程序内部的内存空间,因此当消息被放到接收缓冲区中时,就相当于已经转交给了应用程序。
断开阶段
调用Socket库的close组件,进入断开阶段,最终管道被断开,套接字被删除。
总结:
负责收发消息的是协议栈,网卡驱动和网卡,只有这三者相互配合,数据 才能在网络中游走。