【Java学习笔记】59:DatagramPack和DatagramSocket做UDP通信
2018-02-13 23:57
856 查看
DatagramPack和DatagramSocket
Socket是基于TCP协议的,先建立连接再进行通信的,还可以基于UDP用户数据报协议不建立连接直接发消息。DatagramPack类用于建立Java的UDP数据报对象,其中包含了数据的字节数组,目标主机ip地址和端口号,发送方和接收方的端口号需要一致。
DatagramSocket类所创建的对象用于发送或接收前面的数据报对象,当使用无参构造器时,这个对象使用
.send(DatagramPack dp)方法发送数据报对象dp;当使用单参构造器
DatagramSocket(int port)时,这个对象使用
.receive(DatagramPack dp)方法接收数据报对象到其参数dp中。为了解析得到的DatagramPack对象dp,可以使用
.getAddress()获得其来自哪个主机,
.getData()获取其中的数据的Byte数组,
.getLength()获得数组的长度。
程序
照着课本敲的。两边是等价的,无分服务端和客户端,所以这种方式逻辑上适合用户之间直接通信。CentOS上Host1.java
务必service iptables stop关闭防火墙,否则收不到数据。
package host1; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; import java.util.Scanner; //小电脑CentOS上的程序 public class Host1 { public static void main(String[] args) { Scanner sc; Thread readData;// 读取数据单独用一个线程,接收和发送分开 receiveThread rt = new receiveThread();// 线程的目标对象 readData = new Thread(rt);// 创建子线程 readData.start();// 启动子线程,用来接收消息 /* main线程则用来发送消息 */ byte[] buffer = new byte[1]; try { // 目的主机ip地址 InetAddress ia = InetAddress.getByName("192.168.0.108"); // 构造要发送的数据包(byte数组,数组长度,目的地址,端口号) DatagramPacket dp = new DatagramPacket(buffer, buffer.length, ia, 3838); // DatagramSocket类的无参构造器构造的对象用来发送数据包 DatagramSocket ds = new DatagramSocket(); System.out.println(">输入发送给Shelon的数据"); sc = new Scanner(System.in); while (sc.hasNext())// main线程的阻塞之处 { String mess = sc.nextLine();// 读入为字符串 if (mess.length() == 0)// 输入为空时结束程序 System.exit(0); buffer = mess.getBytes("utf-8");// 转换成字节数组,指明编码utf-8 dp.setData(buffer);// 将读入的字节数组存入要发送的数据包 ds.send(dp);// 发送数据包 System.out.println(">输入发送给Shelon的数据"); } } catch (UnknownHostException e) { e.printStackTrace(); } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } // 接收数据的线程的目标对象类 class receiveThread implements Runnable { @Override public void run() { DatagramPacket dp; DatagramSocket ds = null; byte[] data = new byte[8192];// 用来接收数据包 dp = new DatagramPacket(data, data.length);// 存放接收的数据包 try { // DatagramSocket类的单参构造器(port)构造的对象用来接收数据包 ds = new DatagramSocket(3838); } catch (SocketException e) { e.printStackTrace(); } while (true) { // 注意特判上一个异常发生时是null if (ds == null) break; else try { // 接收数据到参数DatagramPacket对象中 ds.receive(dp); // 从这个对象中的Byte数组里拿出来,指明编码是utf-8转成String String message = new String(dp.getData(), 0, dp.getLength(), "utf-8"); System.out.printf("%25s\n", "收到:" + message);// 前面留25个空 } catch (IOException e) { e.printStackTrace(); } } } }
Win7上Host2.java
package host2; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; import java.util.Scanner; //win7电脑上的程序 public class Host2 { public static void main(String[] args) { Scanner sc; Thread readData;// 读取数据单独用一个线程,接收和发送分开 receiveThread rt = new receiveThread();// 线程的目标对象 readData = new Thread(rt);// 创建子线程 readData.start();// 启动子线程,用来接收消息 /* main线程则用来发送消息 */ byte[] buffer = new byte[1]; try { // 目的主机ip地址 InetAddress ia = InetAddress.getByName("192.168.0.106"); // 构造要发送的数据包(byte数组,数组长度,目的地址,端口号) DatagramPacket dp = new DatagramPacket(buffer, buffer.length, ia, 3838); // DatagramSocket类的无参构造器构造的对象用来发送数据包 DatagramSocket ds = new DatagramSocket(); System.out.println(">输入发送给hostlzh的数据"); sc = new Scanner(System.in); while (sc.hasNext())// main线程的阻塞之处 { String mess = sc.nextLine();// 读入为字符串 if (mess.length() == 0)// 输入为空时结束程序 System.exit(0); buffer = mess.getBytes("utf-8");// 转换成字节数组 dp.setData(buffer);// 将读入的字节数组存入要发送的数据包 ds.send(dp);// 发送数据包 System.out.println(">输入发送给hostlzh的数据"); } } catch (UnknownHostException e) { e.printStackTrace(); } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } // 接收数据的线程的目标对象类 class receiveThread implements Runnable { @Override public void run() { DatagramPacket dp; DatagramSocket ds = null; byte[] data = new byte[8192];// 用来接收数据包 dp = new DatagramPacket(data, data.length);// 存放接收的数据包 try { // DatagramSocket类的单参构造器(port)构造的对象用来接收数据包 ds = new DatagramSocket(3838); } catch (SocketException e) { e.printStackTrace(); } while (true) { // 注意特判上一个异常发生时是null if (ds == null) break; else try { // 接收数据到参数DatagramPacket对象中 ds.receive(dp); // 从这个对象中的Byte数组里拿出来 String message = new String(dp.getData(), 0, dp.getLength(), "utf-8"); System.out.printf("%25s\n", "收到:" + message);// 前面留25个空 } catch (IOException e) { e.printStackTrace(); } } } }
运行结果
CentOS
>输入发送给Shelon的数据 收到:12ok 啊啊啊啊机器学习机器学习 >输入发送给Shelon的数据 刘知昊刘知昊SB >输入发送给Shelon的数据 收到:我的键盘坏掉了 收到:雪碧透心凉心飞扬
Win7
>输入发送给hostlzh的数据 12ok >输入发送给hostlzh的数据 收到:啊啊啊啊机器学习机器学习 收到:刘知昊刘知昊SB 我的键盘坏掉了 >输入发送给hostlzh的数据 雪碧透心凉心飞扬 >输入发送给hostlzh的数据
相关文章推荐
- 【Java学习笔记】58:多线程Socket通信的demo
- java网络编程基础——UDP通信之DatagramSocket
- Androin学习笔记四十二:Java android Socket通信检测(server)连接是否断开
- Java UDP通信:DatagramSocket和DatagramPacket
- java学习笔记---Socket应用网络通信
- Java学习之UDP--DatagramSocket和DatagramPacket
- java学习之路——基于UDP的Socket网络通信实例
- 【Java基础学习笔记】Java中Socket+Swing设计简单通信
- Java学习笔记------一个能相互通信的半双工Socket C/S实例
- JAVA学习笔记Day24——javaTCP UDP网络编程Socket总结
- TCP/IP详解(卷2实现)学习笔记(一)udp的socket通信过程底层实现概述(1)
- [JAVA学习笔记-93]DatagramSocket的线程安全性
- UDP通信(android开发java语言写的)DatagramSocket
- java中请给出UDP的DatagramSocket通信的例子?
- Java与Flex学习笔记(4)----Flex与Java通信之RemoteObject方式
- 【Java学习笔记】UDP客户端/服务器端
- Java与Flex学习笔记(15)----Flex中的Application与Module间的通信
- 黑马程序员________Java中UDP和TCP网络编程学习笔记
- Java学习之路7——UDP通信
- Java与Flex学习笔记(21)----Flex与Java通信方式之WebService