前面的章节我们主要学习了TCP/IP协议栈的原理。但是从一个应用程序的角度,又应该如何利用网络提供的服务呢?这就涉及到应用程序与TCP/IP协议之间的接口问题。
TCP/IP的发展与UNIX操作系统有着密切的联系。UNIX一个重要的特点就是将所有的设备和资源都当作文件看待,按照统一的“打开-读-写-关闭”流程,通过相应的输入和输出操作实现对设备和资源的访问。
TCP/IP网络协议比传统的I/O设备更为复杂,因此,用户进程和网络协议之间的交互面临更多复杂的情况。比如,编程人员既可能创建被动等待的服务器代码,也可能创建主动请求的客户代码;在打开网络资源的时候,也许不能确定发送的目的地址,而需要动态地绑定目的地址;此外,为了适应多种协议,设计人员期望UNIX网络接口应该采用一种通用的机制,以便适应不同协议的需要。例如,如果应用程序提供32位的地址,操作系统可能无法正确解释,而必须由应用程序明确指出这32位代表的是IP地址。
套接字(socket)是网络I/O的基础,它是UNIX操作系统将网络I/O的文件抽象,从而使对网络通信资源的访问与文件访问采用非常相似的方式,例如可以使用传统的read和write操作,如下图所示。
套接字通过一个套接字描述符来进行标识,它与文件描述符有非常相似之处,并且和文件描述符共用一个编码空间。换句话说,如果一个整数编号已经分配作为套接字描述符,那么就不能被分配作为文件描述符。