- 向操作系统内部的协议栈发出委托时,需要按照指定的顺序来调用Socket库中的程序组件。
套接字
- 管道两端的数据出入口称为套接字
- 首先,服务器一方先创建套接字,进入等待状态,然后等待客户端向该套接字连接管道
- 将数据送入套接字就可以收发数据了
- 当数据全部发送完毕之后,断开可以由客户端或服务器任意一方发起
收发数据的操作可以分为4个阶段
- 创建套接字(
创建套接字阶段
) - 将管道连接到服务器端的套接字上(
连接阶段
) - 收发数据(
通信阶段
) - 断开管道并删除套接字(
断开阶段
) - 这4个操作都是由操作系统中的协议栈来执行的,浏览器等应用程序并不会自己去做连接管道、放入数据这些工作,而是委托协议栈来代劳
创建套接字阶段
- 调用Socket库中的socket程序组件创建套接字
- 描述符:用来识别不同的套接字,会在套接字创建完成之后,协议栈返回,并保存在内存中(因为同一台计算机上可能同时存在多个套接字,描述符可以识别出某个特定的套接字)
连接阶段
- 调用Socket库中的名为connect的程序组件来完成这一操作
参数
- 描述符:唯一标识套接字的描述符,将此描述符告知协议栈,协议栈通过此描述符和服务器端的套接字进行连接
- 服务器IP地址:通过DNS服务器查询得到的额服务器的IP地址
- 端口号:确定服务器端特定的套接字,服务器上所使用的端口号都是提前规定好的(Web是80号端口,电子邮件是25号端口)
服务器端向客户端发送消息时,也得知道客户端套接字的端口号:客户端在创建套接字时,协议栈会为这个套接字随便分配一个端口号。接下来,当协议栈执行连接操作时,会将这个随便分配的端口号通知给服务器
通信阶段:传递消息
- 使用write这个程序组件
- 发送的数据是根据用户输入的网址生成的HTTP请求消息
- 当调用write时,需要指定描述符和发送数据,然后协议栈就会将数据发送到服务器
- 由于套接字中已经保存了已连接的通信对象的相关信息,所以只要通过描述符指定套接字,就可以识别出通信对象,并向其发送数据。
- 接收消息的操作是通过Socket库中的read程序组件委托协议栈来完成的
- 当服务器返回响应消息时,read就会负责将接收到的响应消息存放到接收缓冲区中
断开阶段:收发数据结束
- 调用Socket库的close程序组件进入断开阶段,套接字本身也会被删除
- 当浏览器调用read执行接收数据操作时,read会告知浏览器收发数据操作已结束,连接已经断开。浏览器得知后,也会调用close进入断开阶段。