目录
概要
1. 数据报基本知识
之前套接字中例子使用的都是“传输控制协议”(TCP),亦称作“基于数据流的套接字”。根据该协议的设计宗旨,它具有高度的可靠性,而且能保证数据顺利抵达目的地。换言之,它允许重传那些由于各种原因半路“走失”的数据。而且收到字节的顺序与它们发出来时是一样的。当然,这种控制与可靠性需要我们付出一些代价:TCP 具有非常高的开销。
还有另一种协议,名为“用户数据报协议”(UDP),它并不刻意追求数据包会完全发送出去,也不能担保它们抵达的顺序与它们发出时一样。我们认为这是一种“不可靠协议”(TCP 当然是“可靠协议”)。
Java 对数据报的支持与它对TCP 套接字的支持大致相同,但也存在一个明显的区别。对数据报来说,我们在客户和服务器程序都可以放置一个DatagramSocket(数据报套接字),但与ServerSocket 不同,前者不会干巴巴地等待建立一个连接的请求。这是由于不再存在“连接”,取而代之的是一个数据报陈列出来。另一项本质的区别的是对TCP 套接字来说,一旦我们建好了连接,便不再需要关心谁向谁“说话”——只需通过会话流来回传送数据即可。但对数据报来说,它的数据包必须知道自己来自何处,以及打算去哪里。这意味着我们必须知道每个数据报包的这些信息,否则信息就不能正常地传递。DatagramSocket 用于收发数据包,而DatagramPacket 包含了具体的信息。准备接收一个数据报时,只需提供一个缓冲区,以便安置接收到的数据。数据包抵达时,通过DatagramSocket,作为信息起源地的因特网地址以及端口编号会自动得到初化。
所以一个用于接收数据报的DatagramPacket 构建器是:
DatagramPacket(buf, buf.length)
可以重复使用数据报的接收代码,不必每次都建一个新的。每次用它的时候(再生),缓冲区内的数据都会被覆盖。发出一个数据报时,DatagramPacket 不仅需要包含正式的数据,也要包含因特网地址以及端口号,以决定它的目的地。
所以用于输出DatagramPacket 的构建器是:
DatagramPacket(buf, length, inetAddress, port)
这一次,buf(一个字节数组)已经包含了我们想发出的数据。length 可以是buf 的长度,但也可以更短一些,意味着我们只想发出那么多的字节。我们认为TCP 和UDP 端口是相互独立的。也就是说,可以在端口8080 同时运行一个TCP 和UDP 服务程序,两者之间不会产生冲突。
该例类似于前面针对TCP 套接字的
MultiJabberServer 和MultiJabberClient 例子。多个客户都会将数据报发给服务器,后者会将其反馈回最
初发出消息的同样的客户。
2. 服务器端和客户端程序实例
该例类似于前面针对TCP 套接字的MultiJabberServer 和MultiJabberClient 例子。多个客户都会将数据报发给服务器,后者会将其反馈回最初发出消息的同样的客户。