需求描述:
第一步:现在有ClientA向网络中的所有设备的8888端口发送广播,ClientB需要监听8888端口来收到广播信息
第二步:ClientB在收到广播信息后需要给予回执。需要将消息回复过去
参考代码
/**
* 广播出去,并接受收到信息的回执
*/
public class ClientA {
private static final Integer BroadCast_Port = 8888;//广播端口
private static final Integer Receive_Port = 9999;//别人的回执端口
private static final String SENDSTR = "明天都来家里吃饭啊!";
public static void main(String[] args) throws Exception {
System.out.println("准备好我要广播了-------");
MyLisener lisener = lisener();
sendBroadCast();
List<InetAddress> inetAddresses = null;
while(true){
if(99 == System.in.read()){//如果按了c就退出
inetAddresses = lisener.closeAndGetAddress();
break;
}
}
inetAddresses = lisener.closeAndGetAddress();
System.out.println("收到参加聚会的人员信息----------------------");
for (InetAddress inetAddress : inetAddresses) {
System.out.println("人员信息->>>>>"+inetAddress.getHostAddress());
}
System.out.println("------------------------------------------");
System.out.println("所有都结束了");
}
private static void sendBroadCast() throws IOException {
//发送广播
DatagramSocket datagramSocket = new DatagramSocket();
DatagramPacket datagramPacket = new DatagramPacket(SENDSTR.getBytes("UTF-8"),SENDSTR.getBytes().length);
datagramPacket.setPort(BroadCast_Port);
datagramPacket.setAddress(InetAddress.getByName("255.255.255.255"));
datagramSocket.send(datagramPacket);
}
private static MyLisener lisener() throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(1);
MyLisener myLisener = new MyLisener(countDownLatch);
myLisener.start();
countDownLatch.await();
return myLisener;
}
private static class MyLisener extends Thread{
private DatagramSocket ds;
private boolean finished = false;
private final CountDownLatch countDownLatch;
private final List<InetAddress> devices = new ArrayList<>();
private MyLisener(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
ds = new DatagramSocket(Receive_Port);
countDownLatch.countDown();
while(!finished){
byte[] bytes = new byte[100];
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
ds.receive(datagramPacket);
devices.add(datagramPacket.getAddress());
System.out.println("获得数据 ->>>> "+new String(datagramPacket.getData(),0,datagramPacket.getLength()));
}
}catch (Exception e){
// e.printStackTrace();
}
}
public List<InetAddress> closeAndGetAddress(){
if(ds != null){
ds.close();
ds = null;
}
this.finished = true;
//我不允许外面的更改
return Collections.unmodifiableList(devices);
}
}
}
/**
* 用来接收数据
*/
public class ClientB {
private static final Integer Receive_Port = 8888;//广播端口
private static final Integer Send_Port = 9999;//别人的回执端口
private final static String SENDSTR = "好的,我要吃八碗<QAQ>";
public static void main(String[] args) throws IOException {
System.out.println("开始启动");
MyCustomer myCustomer = new MyCustomer();
myCustomer.start();
while(true){
if(99 == System.in.read()){//如果按了c就退出
myCustomer.exit();
break;
}
}
}
private static class MyCustomer extends Thread{
private DatagramSocket ds = null;
private boolean finished = false;
@Override
public void run() {
try {
ds = new DatagramSocket(Receive_Port);
while(!finished){
byte[] bytes = new byte[100];
DatagramPacket receivePacket = new DatagramPacket(bytes, bytes.length);
ds.receive(receivePacket);
System.out.println(new String(receivePacket.getData(),0,receivePacket.getLength()));
//发送数据
System.out.println("发送回执");
DatagramPacket sendPacket = new DatagramPacket(SENDSTR.getBytes(), SENDSTR.getBytes().length);
//发送到广播的那个地址
sendPacket.setAddress(receivePacket.getAddress());
sendPacket.setPort(Send_Port);
ds.send(sendPacket);
}
}catch (Exception e){
}
}
public void exit(){
if(ds != null){
ds.close();
ds = null;
finished = true;
}
}
}
}
代码描述
ClientA代码描述:
此类中创建了一个lisener线程。因为需要开启一个端口来监听别人发来的消息,而且不想阻塞主线程,所以就新开了个线程。
在线程中使用到了countdownLatch,因为现在的设计思路是:先开启监听端口(接受消息的端口)再进行广播发送。也就是说在没有监听的时候让主线程阻塞,当监听了就不阻塞线程,就是使用CountDownLatch来实现的。
ClientB代码描述
此客户端为接受广播消息的一段,并给出回执
这边也创建一个线程。这里代码比较简单,暂无可说。。。
运行结果
clientA运行结果
clientB运行结果