Android网络编程系列 一 Socket抽象层
在《Android网络编程》系列文章中,前面已经将Java的通信底层大致的描述了,在我们了解了TCP/IP通信族架构及其原理,接下来我们就开始来了解基于tcp/ip协议层的Socket抽象层。本篇文章将会让我们清楚的了解和学会使用Socket。
什么是Socket?它又是如何运作的?它的表现形式是什么?等等这些问题,本篇文章将逐步的揭晓。
一. 什么是Socket
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口,你可以借助它建立TCP连接等等,而http是个应用层的协议,它实际上也建立在TCP协议之上。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
然而Socket本身并不是协议,它只是对TCP/IP协议的封装,是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。Socket的出现只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,从而形成了我们知道的一些最基本的函数接口。
二. 它是如何运作的?
首先我们来看下其内部的通信原理,如图:
一台主机的应用程序C要能和另一台主机的应用程序S通信,必须通过 Socket 建立连接,而建立 Socket 连接必须需要底层TCP/IP 协议来建立 TCP 连接。建立 TCP 连接需要底层 IP 协议来寻址网络中的主机。我们知道网络层使用的 IP 协议可以帮助我们根据 IP 地址来找到目标主机,但是一台主机上可能运行着多个应用程序,如何才能与指定的应用程序通信就要通过 TCP 或 UPD 的地址也就是端口号来指定。这样就可以通过一个 Socket 实例唯一代表一个主机上的一个应用程序的通信链路了。
建立Socket连接至少需要一对套接字,其中一个运行于客户端程序C中,称为ClientSocket ,另一个运行于服务器端程序S中,称为ServerSocket 。套接字之间的连接过程分为三个步骤:服务器等待监听,客户端请求,连接建立。
1>.服务器等待监听:ServerSocket 并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。该过程是一个阻塞过程,直到有客户端来链接为止。
2>.客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
3>.连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
在创建 Socket 实例的构造函数正确返回之前,将要进行 TCP 的三次握手协议,TCP 握手协议完成后,Socket实例对象将创建完成,否则将抛出 IOException 错误。具体的三次握手协议可以看《Android网络编程 一 JavaSecurity之JCE(SSL/TLS)》。
三. 它的表现形式是什么?
以上讲述的都属于JAVA I/O 范畴,我们可以看出I/O编程中我们用的就是Socket 和 ServerSocket,通信的数据靠Socket之间的流通道,其次在调用InputStream.read()方法时是阻塞的,它会一直等到数据到来时(或超时)才会返回;同样,在调用ServerSocket.accept()方法时,也会一直阻塞到有客户端连接才会返回,每个客户端连接过来后,服务端都会启动一个线程去处理该客户端的请求。当客户端多时,会创建大量的处理线程。且每个线程都要占用栈空间和一些CPU时间。所以Java NI/O编程就应运而生,它能够很好的解决这些。NI/O编程可以说成非阻塞式I/O,java NIO采用了双向通道(channel)进行数据传输,而不是单向的流(stream),在通道上可以注册我们感兴趣的事件。一共有以下四种事件:比如读、写、客户端链接事件、服务端接收链接事件。NI/O 它由一个专门的线程来处理所有的 I/O 事件,并负责分发。 事件到的时候触发,而不是同步的去监视事件。 线程之间通过 wait,notify 等方式通讯。保证每次上下文切换都是有意义的。减少无谓的线程切换。 Channels、Buffers 、Selectors 三个NIO编程的核心类。关于NIO本篇文件就不多说了,大致的介绍下。 除此之外,它的另外一种表现形式就是在其原有的基础上(socket 和 serversocket)加上了一层安全保护也就是SSL/TLS协议保护层。关于这一层的介绍可以参考《Android网络编程 一 JavaSecurity之JCE(SSL/TLS)》。
四. 小结
以上呢就大致的讲述了Socket及其相关概念。在实际开发中,我们可能会遇到各式各样的问题,遇到问题不可拍,可怕的是我们不了解问题。关于更深更多的知识就得靠自己日积月累了。