前面介绍了如何经过Socket接口传输文本与文件,在示例代码中,Socket客户端得先调用connect方法链接服务端,确认双方成功连上后才能继续运行后面的代码,这种确认机制确保客户端与服务端的的确确成功链接了,于是是可靠的网络链接,而且该可靠链接属于TCP链接。为啥这么说呢?由于TCP协议(全称“Transmission Control Protocol”,传输控制协议)不只是一种传输层的通讯协议,并且它具有面向可靠链接、以及基于字节流两大特征。以前联合Socket与ServerSocket实现消息通讯的过程,正是听从TCP协议的精神
虽然可靠链接可以保证必定会把信息送达对方,可是有时须要批量向一群目标设备发送消息,也就是俗称的“群发”,假若每一个设备都经历创建链接、发送消息、关闭链接三个步骤,整个群发操做的资源开销将是巨大的。鉴于群发功能通常为单向过程,消息发送方既不关心那些接收方是否收到消息,也不期望那些接收方会有什么反馈结果,总之消息发送方就像电台作广播那样,在固定的频率波段发送信息,它才无论别人的收音机有没有开着、有没有接收这个频道,只有收音机开着且调至对应的频道,方能收到该电台的广播节目。像这样的广播功能用到了传输层的另外一种UDP协议(全称“User Datagram Protocol”,用户数据报协议),因为UDP并不是可靠链接,它只管扔沙包,而无论对方有没有接到沙包,所以实现过程相较TCP要更简单,毕竟随便丢东西不费多少劲儿。
就UDP协议而言,Java给出的实现工具包括数据包套接字DatagramSocket和数据包裹DatagramPacket。其中DatagramSocket提供了设备间的数据交互动做,它的主要方法说明以下:
构造方法:对于服务端来讲,构造方法须要指定待侦听的端口号;对于客户端来讲,构造方法无需任何参数。
receive:该方法用于服务端接收数据。
send:该方法用于客户端发送数据。
close:关闭数据包套接字。
注意上面的receive和send两个方法,它们的输入参数类型为DatagramPacket,也就是说,必须先将数据封装为DatagramPacket格式,才能在UDO的服务端与客户端之间传输。下面是DatagramPacket的主要方法说明:
用于服务端的构造方法:此时构造方法只有两个参数,分别为字节数组及其长度。
用于客户端的构造方法:此时构造方法拥有四个参数,依次为字节数组、数组长度、数据要发往的服务器InetAddress地址、服务器的端口号。
getData:获取数据包裹里的字节数组。
getOffset:获取数据的起始偏移。
getLength:获取数据的长度。html
接下来举个简单的应用案例,采起UDP协议在设备之间传输文本消息,此时的UDP服务端代码示例以下:数组
//演示Socket服务器的运行(UDP协议的不可靠链接) public class TestUdpServer { private static final int UDP_PORT = 61000; // UDP传输专用端口 public static void main(String[] args) { startUdpServer(); // 启动UDP服务器接收文本消息 } // 启动UDP服务器接收文本消息 private static void startUdpServer() { PrintUtils.print("UDP服务器已启动"); // 建立一个监听指定端口的DatagramSocket对象 try (DatagramSocket socket = new DatagramSocket(UDP_PORT)) { byte[] data = new byte[1024]; // 接收数据的字节数组 // 建立一个DatagramPacket对象,并指定数据包的字节数组及其大小 DatagramPacket packet = new DatagramPacket(data, data.length); while (true) { // 持续侦听 socket.receive(packet); // 接收到了数据包 // 把收到的数据转换为字符串。字符串构造方法的三个参数依次为: // 已收到的数据、起始偏移、数据的长度。 String message = new String(packet.getData(), packet.getOffset(), packet.getLength()); PrintUtils.print("UDP服务器收到消息:" + message); } } catch (Exception e) { e.printStackTrace(); } } }
原来UDP方式的服务端代码如此简洁,UDP客户端的代码一样简约,即使是发送两条消息的完整代码也只有如下数行:服务器
//演示Socket客户端的运行(UDP协议的不可靠链接) public class TestUdpClient { // 如下为Socket服务器的IP和端口,根据实际状况修改 private static final String SOCKET_IP = "192.168.1.8"; private static final int UDP_PORT = 61000; // UDP传输专用端口 public static void main(String[] args) { startUdpClient("Hello World"); // 启动UDP客户端发送文本消息 startUdpClient("你好,世界"); // 启动UDP客户端发送文本消息 } // 启动UDP客户端发送文本消息 private static void startUdpClient(String message) { PrintUtils.print("UDP客户端发送消息:" + message); // 建立一个DatagramSocket对象 try (DatagramSocket socket = new DatagramSocket()) { // 根据IP地址得到对应的网络地址对象 InetAddress serverAddress = InetAddress.getByName(SOCKET_IP); byte data[] = message.getBytes(); // 把字符串转换为字节数组 // 建立一个DatagramPacket对象,构造方法的四个参数依次为: // 待发送的数据、数据的长度、服务器的网络地址、服务器的端口号。 DatagramPacket packet = new DatagramPacket(data, data.length, serverAddress, UDP_PORT); socket.send(packet); // 向服务器发送数据包 } catch (Exception e) { e.printStackTrace(); } } }
而后前后运行服务端与客户端的测试代码,观察到的客户端日志以下:网络
12:16:12.316 main UDP客户端发送消息:Hello World 12:16:12.366 main UDP客户端发送消息:你好,世界
同时观察到下面的服务端日志:socket
12:15:46.998 main UDP服务器已启动 12:16:12.366 main UDP服务器收到消息:Hello World 12:16:12.368 main UDP服务器收到消息:你好,世界
根据以上的客户端日志以及服务端日志,可知经过UDP协议也成功完成了文本传输。工具
更多Java技术文章参见《Java开发笔记(序)章节目录》测试