详细介绍了java中的网络通信机制,尤其是UDP协议,通过对UDP的基本使用进行举例说明如何使用UDP进行数据的发送接收,并举了两个小demo说明UDP的使用注意事项。
UDP协议原理图解:
UDP协议:需要借助于InetAddress来获取设备的IP地址,以及姓名
1 import java.io.IOException; 2 import java.net.Inet4Address; 3 import java.net.InetAddress; 4 import java.net.UnknownHostException; 5 6 public class InetAddressDemo { 7 public static void main(String[] args) throws IOException { 8 // InetAddress address = InetAddress.getByName("10.129.123.23"); 9 InetAddress address = InetAddress.getByName("ooo-PC"); 10 // InetAddress address = InetAddress.getByName("lpp-PC"); 11 12 // 获取该ip地址对象的IP地址和主机名 13 String name = address.getHostName(); 14 String ip = address.getHostAddress(); 15 16 System.out.println(name); 17 System.out.println(ip); 18 } 19 }
1 /* 2 * 网络通讯三要素: 3 * 1.IP地址:InetAddress 网络中设备的标识,不易记忆,可用主机名; 4 * 2.端口号:用于标识进程的逻辑地址,不同进程的标识传输协议通讯的规则;用于标识进程的逻辑地址,不同进程的标识, 5 * 有效端口:0~65535,其中0~1024系统使用或保留端口。 6 * 3.常见协议:TCP,UDP。 7 */ 8 9 /* 10 * UDP协议 11 * 将数据源和目的封装成数据包中,不需要建立连接; 12 * 每个数据报的大小在限制在64k; 13 * 因无连接,是不可靠协议; 14 * 不需要建立连接,速度快 15 */ 16 17 /* 18 * Socket套接字: 19 * 网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的 标识符套接字。 20 * Socket原理机制:通信的两端都有Socket。 21 * 网络通信其实就是Socket间的通信。 22 * 数据在两个Socket间通过IO传输。 23 */ 24 25 26 27 28 //第一部分代码是接收端,一般是先开接收端的代码,再开发送端 29 //接收端代码的创建步骤如下: 30 /* 31 * UDP协议接收数据: 32 * 1.创建接收端socket对象 33 * 2.创建一个数据包(接收数据的容器) 34 * 3.调用socket的对象的接收方法接收数据 35 * 4.解析数据,并显示在控制台 36 * 5.释放资源 37 */ 38 39 import java.io.IOException; 40 import java.net.DatagramPacket; 41 import java.net.DatagramSocket; 42 import java.net.InetAddress; 43 import java.net.SocketException; 44 45 /* 46 * 对于里面创建对象的部分进行优化直接链式编程 47 * java.net.BindException: Address already in use: Cannot bind 48 * 该端口已经被使用了,有可能是第二次调用或者第一次调用的时候该端口被其它程序使用。 49 */ 50 public class ReceiveDemo { 51 public static void main(String[] args) throws IOException { 52 // 创建接收端数socket对象,指定端口。 53 DatagramSocket ds = new DatagramSocket(10086); 54 // 接收数据 55 byte[] buf = new byte[1024]; 56 // int length = buf.length; 57 DatagramPacket dp = new DatagramPacket(buf, buf.length); 58 ds.receive(dp); // 将接受的数据放进dp数据报包中 59 // 解析数据,获取IP地址以及数据报包中的内容 60 // InetAddress address = dp.getAddress(); 61 // String ip = address.getHostAddress(); 62 // byte[] bys = dp.getData(); 63 // int len = dp.getLength(); // 数据报包的实际长度 64 65 String ip = dp.getAddress().getHostAddress(); 66 String s = new String(dp.getData(), 0, dp.getLength()); 67 68 System.out.println(ip + ":--" + s); 69 70 // 释放资源 71 ds.close(); 72 73 } 74 } 75 76 77 //---------------------------------------- 78 //下面是发送端的代码,与上面分开在两个类 79 80 import java.io.IOException; 81 import java.net.DatagramPacket; 82 import java.net.DatagramSocket; 83 import java.net.InetAddress; 84 import java.net.SocketException; 85 86 public class SendDemo { 87 public static void main(String[] args) throws IOException { 88 // 发送端socket对象 89 DatagramSocket ds = new DatagramSocket(); 90 91 // 数据打包 92 byte[] bys = "java".getBytes(); 93 // int len = bys.length; 94 // InetAddress address = InetAddress.getByName("lpp-PC"); 95 // int port = 10086; 96 97 DatagramPacket dp = new DatagramPacket(bys, bys.length, 98 InetAddress.getByName("lpp-PC"), 10086); 99 100 // 发送数据 101 ds.send(dp); 102 103 // 释放资源 104 ds.close(); 105 } 106 }
1 /* 2 * 多线程实现在一个代码里面姐发送又接受数据 3 * 在发送端从键盘录入数据,一直读到886结束数据的录入发送,键盘录入一句就接受一句,接收端一直开着等着数据的发送。 4 */ 5 6 //首先是main方法 7 8 import java.io.IOException; 9 import java.net.DatagramSocket; 10 import java.net.SocketException; 11 12 /* 13 * 通过多线程 14 */ 15 public class chatRoomDemo { 16 public static void main(String[] args) throws IOException { 17 // 接收端,发送端socket 18 DatagramSocket dsSend = new DatagramSocket(); 19 DatagramSocket dsReceive = new DatagramSocket(10086); 20 21 SendThread st = new SendThread(dsSend); 22 ReceiveThread rt = new ReceiveThread(dsReceive); 23 24 // 线程开启 25 Thread sendThread = new Thread(st); 26 Thread receiverThread = new Thread(rt); 27 28 sendThread.start(); 29 receiverThread.start(); 30 } 31 } 32 33 //-------------------------------------------- 34 //接收端线程的创建 35 import java.io.IOException; 36 import java.net.DatagramPacket; 37 import java.net.DatagramSocket; 38 39 public class ReceiveThread implements Runnable { 40 private DatagramSocket ds; 41 42 public ReceiveThread(DatagramSocket ds) { 43 // 通过构造方法进行初始化 44 this.ds = ds; 45 } 46 47 @Override 48 public void run() { 49 // TODO Auto-generated method stub 50 while (true) { 51 try { 52 byte[] buf = new byte[1024]; 53 DatagramPacket dp = new DatagramPacket(buf, buf.length); 54 ds.receive(dp); 55 56 String ip = dp.getAddress().getHostAddress(); 57 58 String s = new String(dp.getData(), 0, dp.getLength()); 59 60 System.out.println(ip + "--->" + s); 61 } catch (IOException e) { 62 e.printStackTrace(); 63 } 64 } 65 } 66 } 67 68 //--------------------------------------- 69 //发送端线程的创建 70 71 import java.io.BufferedReader; 72 import java.io.IOException; 73 import java.io.InputStream; 74 import java.io.InputStreamReader; 75 import java.net.DatagramPacket; 76 import java.net.DatagramSocket; 77 import java.net.InetAddress; 78 79 public class SendThread implements Runnable { 80 private DatagramSocket ds; 81 82 public SendThread(DatagramSocket ds) { 83 this.ds = ds; 84 } 85 86 @Override 87 public void run() { 88 // TODO Auto-generated method stub 89 try { 90 BufferedReader br = new BufferedReader(new InputStreamReader( 91 System.in)); 92 String line = null; 93 while ((line = br.readLine()) != null) { 94 if ("886".equals(line)) { 95 break; 96 } 97 byte[] buf = line.getBytes(); 98 DatagramPacket dp = new DatagramPacket(buf, buf.length, 99 InetAddress.getByName("lpp-PC"), 10086); 100 101 ds.send(dp); 102 } 103 } catch (IOException e) { 104 e.printStackTrace(); 105 } 106 // //释放资源 107 // ds.close(); 108 } 109 110 }