都是从网上搜取的资料,经过自己整合,测试成功。
使用java 的UDP进行广播,要分两步走,首先要加入到广播组地址,其次要建立套接字传输信息
关于广播,涉及到MulticastSocket,他用于接收广播的信息,前提是要将它加入到广播组,组播的地址是保留的D类地址从224.0.0.0—239.255.255.255,而且一些地址有特定的用处如,224.0.0.0—244.0.0.255只能用于局域网中路由器是不会转发的,并且224.0.0.1是所有主机的地址,224.0.0.2所有路由器的地址,224.0.0.5所有ospf路由器的地址,224.0.13事PIMv2路由器的地址;239.0.0.0—239.255.255.255是私有地址(如192.168.x..x);224.0.1.0—238.255.255.255可以用与Internet上的。这里我们就选取230.0.0.1作为我们的广播地址。
此软件类似于飞鸽,用于局域网通信,每个客户端上线都要寻找局域网其他主机并把自己的信息和所有主机交换,以此模式更新。。。
class lanSend {
/**
* @param args
* @throws Exception
*/
//广播地址
private static final String BROADCAST_IP = "230.0.0.1";//广播IP
private static final int BROADCAST_INT_PORT = 40005; // 不同的port对应不同的socket发送端和接收端
MulticastSocket broadSocket ;//用于接收广播信息
InetAddress broadAddress ;//广播地址
DatagramSocket sender ;//数据流套接字 相当于码头,用于发送信息
public lanSend() {
try {
//初始化
broadSocket=new MulticastSocket(BROADCAST_INT_PORT);
broadAddress = InetAddress.getByName(BROADCAST_IP);
sender = new DatagramSocket();
} catch (Exception e) {
// TODO: handle exception
System.out.println("*****lanSend初始化失败*****"+e.toString());
}
}
void join() {
try{
broadSocket.joinGroup(broadAddress); //加入到组播地址,这样就能接收到组播信息
new Thread(new GetPacket()).start(); //新建一个线程,用于循环侦听端口信息
}catch (Exception e) {
// TODO: handle exception
System.out.println("*****加入组播失败*****");
}
}
//广播发送查找在线用户
void sendGetUserMsg() {
byte[] b=new byte[1024];
DatagramPacket packet; //数据包,相当于集装箱,封装信息
try{
b = ("find@"+lanDemo.msg).getBytes();
packet = new DatagramPacket(b, b.length, broadAddress, BROADCAST_INT_PORT); //广播信息到指定端口
sender.send(packet);
System.out.println("*****已发送请求*****");
}catch (Exception e) {
System.out.println("*****查找出错*****");
}
}
//当局域网内的在线机子收到广播信息时响应并向发送广播的ip地址主机发送返还信息,达到交换信息的目的
void returnUserMsg(String ip){
byte[] b=new byte[1024];
DatagramPacket packet;
try {
b=("retn@"+lanDemo.msg).getBytes();
packet = new DatagramPacket(b,b.length,InetAddress.getByName(ip),BROADCAST_INT_PORT);
sender.send(packet);
System.out.print("发送信息成功!");
} catch (Exception e) {
// TODO: handle exception
System.out.println("*****发送返还信息失败*****");
}
}
//当局域网某机子下线是需要广播发送下线通知
void offLine(){
byte[] b=new byte[1024];
DatagramPacket packet;
try {
b=("offl@"+lanDemo.msg).getBytes();
packet = new DatagramPacket(b,b.length,broadAddress,BROADCAST_INT_PORT);
sender.send(packet);
System.out.println("*****已离线*****");
} catch (Exception e) {
// TODO: handle exception
System.out.println("*****离线异常*****");
}
}
class GetPacket implements Runnable { //新建的线程,用于侦听
public void run() {
DatagramPacket inPacket;
String[] message;
while(true){
try {
inPacket=new DatagramPacket(new byte[1024], 1024);
broadSocket.receive(inPacket); //接收广播信息并将信息封装到inPacket中
message=new String(inPacket.getData(),0,inPacket.getLength()).split("@"); //获取信息,并切割头部,判断是何种信息(find--上线,retn--回答,offl--下线)
if(message[1].equals(lanDemo.ip))continue; //忽略自身
if(message[0].equals("find")){ //如果是请求信息
System.out.println("新上线主机:"+" ip:"+message[1]+" 主机:"+message[2]);
returnUserMsg(message[1]);
}
else if(message[0].equals("retn")){ //如果是返回信息
System.out.println("找到新主机:"+" ip:"+message[1]+" 主机:"+message[2]);
}
else if(message[0].equals("offl")){ //如果是离线信息
System.out.println("主机下线:"+" ip:"+message[1]+" 主机:"+message[2]);
}
} catch (Exception e) {
// TODO: handle exception
System.out.println("线程出错 "+e);
}
}
}
}
}
public class lanDemo{
//全局变量
public static String msg;
public static String ip;
public static String hostName;
public static void main(String[] args){ //程序入口点
lanSend lSend;
try {
InetAddress addr = InetAddress.getLocalHost();
ip=addr.getHostAddress().toString();
hostName = addr.getHostName().toString();
msg= ip+"@"+hostName;
lSend=new lanSend();
lSend.join(); //加入组播,并创建线程侦听
lSend.sendGetUserMsg(); //广播信息,寻找上线主机交换信息
Thread.sleep(3000); //程序睡眠3秒
lSend.offLine(); //广播下线通知
} catch (Exception e) {
System.out.println("*****获取本地用户信息出错*****");
}
}
}
至此就基本完成了 上线,下线,广播功能,只是个demo,仅供参考。