需求:
通过键盘录入获取要发送的信息。
将发送和接收分别封装到两个线程中。
代码:
发送信息的 Runnable实现类:
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; /** * 2018年5月7日 下午7:25:49 * @author <a href="mailto:[email protected]">宋进宇</a> * UDP聊天程序 * 通过键盘录入获取要发送的信息。 * 将发送和接收分别封装到两个线程中。 * 接收端 线程 */ public class SendThread implements Runnable { DatagramSocket ds = null; //用来发送数据报的套接字 InetAddress receiverIp = null; //接收端的IP int receicerPort = -1 ; //接收端的端口号 /** * 构造方法,需要传入 用来发送 数据报的套接字--ds,接收端的Ip--receiverIp,接收端的端口号--receicerPort * @param ds 发送数据报的套接字 * @param receiverIp 接收端的IP * @param receicerPort 接收端的端口号 */ public SendThread( DatagramSocket ds, InetAddress receiverIp, int receicerPort ) { this.ds = ds; this.receiverIp = receiverIp; this.receicerPort = receicerPort; } @Override public void run() { //获得控制台输入流 Scanner sc = new Scanner( System.in ); //通过 ctrl+z 退出发送 while ( sc.hasNext() ) { //读取一行消息 String mes = sc.nextLine(); //当发生消息为 over! 结束发送 if ( "over!".equals( mes ) ) { break; } DatagramPacket dp = null; try { //把消息进行编码 //把 消息的字节码 、接收端Ip和接收端端口号 封装成一个 数据报 包 byte[] buf = mes.getBytes( "UTF-8" ); //把 消息的字节码 、接收端Ip和接收端端口号 封装成一个 数据报 包 dp = new DatagramPacket( buf, buf.length, receiverIp, receicerPort ); //通过 发送数据报的套接字 进行发送 ds.send( dp ); } catch (IOException e) { break; } } sc.close(); ds.close(); } //测试 public static void main(String[] args){ DatagramSocket senderDs = null; try { //创建 发送端的 数据报套接字 senderDs = new DatagramSocket(); } catch (SocketException e) { return; } try { //创建一个发送端线程 Thread sender = new Thread( new SendThread( senderDs, InetAddress.getByName( "127.0.0.1" ), 8888 ) ); //启动线程 进行 发送消息 sender.start(); } catch (UnknownHostException e) { return ; } } }
接收信息的 Runnable实现类:
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; /** * 2018年5月7日 下午7:25:43 * @author <a href="mailto:[email protected]">宋进宇</a> * UDP聊天程序 * 通过键盘录入获取要发送的信息。 * 将发送和接收分别封装到两个线程中。 * 发送端 线程 */ public class ReceiveThread implements Runnable{ DatagramSocket ds = null; //接收端的 数据报套接字 int port = -1; //接收端的端口号 /** * 构造方法,传入接收端的 数据报套接字--ds和接收端的端口号--port * @param ds 数据报套接字 * @param port 端口号 */ public ReceiveThread(DatagramSocket ds, int port) { this.ds = ds; this.port = port; } @Override public void run() { //只要 发送端 有发送消息 接收端就处理 while ( true ) { //创建一个用来接收的数据报的字节数组 byte[] buf = new byte[1024]; //封装 一个 接收 数据报 的包 DatagramPacket dp = new DatagramPacket( buf, buf.length ); try { //等待 发送端发送消息 ds.receive( dp ); //这里是阻塞的 //能到这里 说明发送端发来消息了 //先获取 发送端的 ip InetAddress senderIp = dp.getAddress(); //把 消息的字节数组 进行 解析 String mes = new String( dp.getData(), 0, dp.getLength(), "UTF-8" ); //在控制台 打印 发送端的地址 和 消息内容 System.out.println( senderIp.getHostAddress() + ":" + mes ); } catch (IOException e) { break; } } } //测试 public static void main(String[] args){ DatagramSocket receiveDs = null; try { //创建一个 接收 数据报的套接字 receiveDs = new DatagramSocket( 8888 ); } catch (SocketException e) { return; } //创建一个 接收端线程 Thread receicer = new Thread( new ReceiveThread( receiveDs , receiveDs.getLocalPort() ) ); //启动 接收端线程 receicer.start(); } }
用户1:
import java.io.IOException; import java.net.DatagramSocket; import java.net.InetAddress; public class User1 { //这里为了代码 简洁 直接抛异常 public static void main(String[] args) throws IOException { //自己用来发送数据报的端口号 10087 DatagramSocket sendDs = new DatagramSocket(10087); InetAddress receiverIp = InetAddress.getByName( "127.0.0.1" ); //对方用来接收数据报的端口号 int receicerPort = 10001; Thread send = new Thread( new SendThread( sendDs, receiverIp, receicerPort ) ); //自己的用来接收数据报 的 端口号 10086 DatagramSocket receiveDs = new DatagramSocket(10086); Thread receive = new Thread( new ReceiveThread( receiveDs, 10086 ) ) ; send.start(); receive.start(); } }
用户2:
import java.io.IOException; import java.net.DatagramSocket; import java.net.InetAddress; public class User2 { //这里为了代码 简洁 直接抛异常 public static void main(String[] args) throws IOException { //自己用来发送数据报的端口号 10000 DatagramSocket sendDs = new DatagramSocket(10000); InetAddress receiverIp = InetAddress.getByName( "127.0.0.1" ); //对方用来接收数据报的端口号 int receicerPort = 10086; Thread send = new Thread( new SendThread( sendDs, receiverIp, receicerPort ) ); //自己用来接收数据报的端口号 10001 DatagramSocket receiveDs = new DatagramSocket(10001); Thread receive = new Thread( new ReceiveThread( receiveDs, 10001 ) ) ; send.start(); receive.start(); } }