需求:
通过键盘录入获取要发送的信息。
将发送和接收分别封装到两个线程中。
代码:
发送信息的 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:447441478@qq.com">宋进宇</a>* UDP聊天程序* 通过键盘录入获取要发送的信息。* 将发送和接收分别封装到两个线程中。* 接收端 线程*/
public class SendThread implements Runnable {DatagramSocket ds = null; //用来发送数据报的套接字InetAddress receiverIp = null; //接收端的IPint 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;}@Overridepublic 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:447441478@qq.com">宋进宇</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;}@Overridepublic void run() {//只要 发送端 有发送消息 接收端就处理while ( true ) {//创建一个用来接收的数据报的字节数组byte[] buf = new byte[1024];//封装 一个 接收 数据报 的包DatagramPacket dp = new DatagramPacket( buf, buf.length );try {//等待 发送端发送消息ds.receive( dp ); //这里是阻塞的//能到这里 说明发送端发来消息了//先获取 发送端的 ipInetAddress 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 {//自己用来发送数据报的端口号 10087DatagramSocket sendDs = new DatagramSocket(10087);InetAddress receiverIp = InetAddress.getByName( "127.0.0.1" );//对方用来接收数据报的端口号int receicerPort = 10001;Thread send = new Thread( new SendThread( sendDs, receiverIp, receicerPort ) );//自己的用来接收数据报 的 端口号 10086DatagramSocket 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 {//自己用来发送数据报的端口号 10000DatagramSocket sendDs = new DatagramSocket(10000);InetAddress receiverIp = InetAddress.getByName( "127.0.0.1" );//对方用来接收数据报的端口号int receicerPort = 10086;Thread send = new Thread( new SendThread( sendDs, receiverIp, receicerPort ) );//自己用来接收数据报的端口号 10001DatagramSocket receiveDs = new DatagramSocket(10001);Thread receive = new Thread( new ReceiveThread( receiveDs, 10001 ) ) ;send.start();receive.start();}
}