如前文所说,不同类型的Socket与不同类型的底层协议族以及同一协议族中的不同协议相关联。而我想说的主要就是TCP/IP协议族中的内容。现在TCP /IP协议族中的主要socket类型为"流套接字(stream socket)"和"数据报套接字(datagram socket)"。如果类比到现实中 stream socket类似于打电话沟通,datagram socket类似于写信沟通。当然,其他协议族当然也有相应的stream socket和datagram socket。
我学习的时候喜欢把类似的事物的异同点相比较,因此我就先从相同点开始说起。 一.Client和Server 无论是打电话还是写信,总会有打电话的一 方和写信的一方,相对应的就会有接电话的一方和收信的一方。后者通过回信或者接听电话对请求发出者作出相应。互联网通信也与这个过程类似。客户端 (client)和服务器(server)这两个术语代表了这两种不同的角色:client是通信的发起者,而server则会被动的等待客户端发起 信,并对其做出响应。
这里要提出的一点是,区分client和server的关键点是谁是请求的发出者,谁是请求的响应者。因此,client和 server之间的角色是可以互换的。一旦原先的client变成了请求的响应者,那么client就变成了server,反之亦然。server并不是 高配置的装了oracle等数据的高级服务器,client也并不是就是指个人电脑,也不是浏览器。记住,client和server只是对请求的发出者 和请求的响应者的一种抽象概念。
为什么要区分这两者呢?因为一个程序是作为client和server决定了它在于其对等端(peer)建立通信时所使用的Socket API的形式。什么叫对等端?客户端的对等端就是服务器,反之亦然。更进一步来说,是因为client首先需要知道server的所在地,也就是要知道 server的IP和port,但是反之则不需要。因为如果有必要,server可以通过相应的API来获取其client的地址。这与打电话非常类似, 被呼叫者不需要知道拨电话者的号码就可以接听电话,如果有需要,办个来电显示就可以知道打电话方的电话号码。只要通信建立成功,server和 client就没有什么区别了。(什么,接听免费?打电话收费?好吧,我承认这个是区别之一)
二.TCP Socket(stream socket)
在TCP/IP协议族中,Stream socket对应是以TCP作为其端对端协议,提供了一个基于连接的可信赖的“字节流”服务。
以下就是我第一次读到类似的话时产生的疑问,一直记录在我的书上:
1.什么是流?
2.什么是基于连接?连接又是什么?
3.什么是可信赖?到底可信赖到什么程度?难道发送端这边断电了接收端仍然还能接到数据?
我相信也会有人产生和我类似的疑问
1. 流简单来说就是一个简单有序的字节序列。注意它是有序的。很容易理解输入流就是以有序的方式写入新的字节,而输出流则是读取字节。因为TCP Socke是基于流的,所以我们可以猜到Socket实例中都会维护着相应的InputStream对象和OutputStream对象。当我们通过 Socket的OutputStream输出数据后,这些字节最终能在连接的另一端通过InputStream读取出来。
明白TCP传送的是一个没有记录边界概念的字节流。这一点很重要,可以总结为TCP中没有用户可见的"分组"概念,它只是传送了一个字节流,我们无法准确地预测在一个特定的读操作中会返回多少字节。最最简单的例子来说,你通过 OutputStream send 3次的数据可能 OutputStream read 2次就读取完了,而这中间又可能有多种情况存在。这里涉及到TCP的可靠性这一性质,这一点将在接下来的文章里细说。
2.和字节序列在网络的环境中称作报文一样,这里的“连接”也是一个基于特定上下文所使用的词。要说连接先从"无连接”来说更容易明白。很显然,如果不同的主机间需要通信,那么肯定需要以某种方式连接起来,无论是有线的还是无线的方式。那么无连接通信指的到底是什么?
回答就是,基于连接和无连接指的是一种协议。也就是说,在这里的连接并不指的是物理介质,而是一种传输的方式,说明了如何在物理介质上来传输数据。无论是基于连接还是无连接,都有可能在同一条网线上传送着数据。
对TCP来说,连接完全是"想象"的。它是由端点(client 和 server)所记忆的状态组成的,并不存在"物理"连接。虽然我们前面用打电话来类比TCP,但打电话的时候是有物理连接的。这 里的连接是指,只要连接的双方认为 TCP 连接存在,并且可以互相发送 IP packet,那么 TCP 连接就一直存在。简单来说,就是一端认为另一端能够接受数据,就记录数据的发送状态并把数据发送出去,除非知道另一端不再能接收到数据了。也就是说,所谓 的连接,就是client认为我能把数据传送到server,server是存在的。而server认为我应该等待client把数据传送过来。而 我们认为连接存在是通过三次握手来实现的。这其中又会产生问题,问题在于连接是想象的,因此并不是实时的。也就是说并不是像你拔掉网线后在右下角的连接提 示就会有个红叉叉出现。当一端出问题的时候,另一端可能仍然会认为连接是存在的。