这个是个简单的程序,用组播和定时器实现同步选举。只是一个作业,用来熟悉组播和定时器的使用。
代码说明:
1).选举人类及选举动作的线程类请参照Voter.java 和 VoteTask.java两个文件
2).运行测试test.bat之前请修改voter.bat中的参数
java Voter 239.1.2.3 3456 Jacky 55 40
第一个参数为选举类对象,第二个参数为组播组地址,第三个参数为监听端口,
第三个参数为选举线程名字前缀,后缀为100以内的一个随机数,第四五个参数为同步选举的定时时间,以此刻的时间为基准,在第四个参数指定的分钟,第五个参数指定的秒的那一时刻开始选举。比如现在是14点18分45秒,把第四五个参数分别设成19 20 那么将在14点19分20 秒开始选举。
默认为启动8个选举进程,8个人参选,如果要修改参选人数请修改test.bat文件
//
Voter.java
import
java.io.IOException;
import
java.net.
*
;
import
java.util.
*
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
class
Voter
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public static void main(String[] args)...{
InetAddress group = null;
int port = 0;
MulticastSocket socket = null;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
String myName;
String min;
String sec;
if(args.length != 5)
System.out.println("Five command-line arguments are execte");
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
else...{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
try...{
group = InetAddress.getByName(args[0]); //组播地址
port = Integer.parseInt(args[1]); //监听端口
myName = new String(args[2] + (int)(Math.random()*100)); //线程名字
min = args[3]; //同步选举定时器的分钟参数
sec = args[4]; //同步选举定时器的秒钟参数
String msg = new String(myName + " " + ((int)(Math.random()*100))%2);
System.out.println(msg); //我的选票和信息
Calendar cal = Calendar.getInstance(); //获取当前时间
int minute = Integer.parseInt(min);
int second = Integer.parseInt(sec);
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
if(minute >= 60 || minute < 0 || second >= 60 || second < 0)...{
System.out.println("时间参数有误!!! 程序退出!!!");
return ;
}
cal.set(Calendar.MINUTE, minute); //设定定时器的分钟
cal.set(Calendar.SECOND,second); //设定定时器的秒钟
Date date = cal.getTime();
socket = new MulticastSocket(port); //组播socket
socket.joinGroup(group); //加入组播组
Timer timer = new Timer(); //定时器
TimerTask task = new VoteTask(socket, group, port, msg, timer); //定时任务——选举任务
timer.schedule(task, date); //开启定时器
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
} catch (UnknownHostException e)...{
e.printStackTrace();
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
} catch (IOException e)...{
e.printStackTrace();
}
}
}
}
//
VoteTask.java
import
java.io.
*
;
import
java.net.
*
;
import
java.util.
*
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
class
VoteTask
extends
TimerTask
...
{
static final int MAX_LEN = 30;
private MulticastSocket socket = null;
private InetAddress group;
private int port;
private String msg;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
private String[] candidate= new String[]...{new String("John"), new String("Smith")}; //候选人
private int[] counter = new int[2];
private boolean timeOut = false;
private Timer timer = null; //持有定时器的引用
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public VoteTask(MulticastSocket socket, InetAddress group, int port, String msg, Timer timer )...{
this.socket = socket;
this.group = group;
this.port = port;
this.msg = msg;
this.timer = timer;
counter[0] = counter[1] = 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void run()...{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
try...{
byte[] data = msg.getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, group, port);
socket.send(packet); //发送我的选举信息
socket.setTimeToLive(32);
System.out.println("My vote: " + msg);
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
while(!timeOut)...{
byte[] temp = new byte[MAX_LEN];
packet = new DatagramPacket(temp, temp.length, group, port);
socket.setSoTimeout(5000);
socket.receive(packet); //接收其他选举人的信息 并打印出来
String s = new String(packet.getData(), 0, packet.getLength());
count(s); //计算候选人的得票情况
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
}catch(SocketTimeoutException ste)...{
timeOut = true;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
}catch (IOException e)...{
e.printStackTrace();
}
System.out.println(candidate[0] + " " + counter[0] + ", " + candidate[1] + " " + counter[1]);
System.out.println("Total vote: " + (counter[0] + counter[1]));
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
if(socket != null)...{
socket.close();
System.out.println("选举完毕!!! 程序退出!!!");
timer.cancel(); //关闭定时器
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**计算候选人的得票情况
* @param s
*/
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
private void count(String s)...{
String[] strs = s.split(" ");
counter[Integer.parseInt(strs[1])]++;
System.out.println("Get one vote from " + strs[0] + " for " + candidate[Integer.parseInt(strs[1])]);
}
}
voter.bat文件内容:
java Example2SenderReceiver 239.1.2.3 23465 HELLO_JACKY
pause
test.bat文件内容:
start voter.bat
start voter.bat
start voter.bat
start voter.bat
start voter.bat
start voter.bat
start voter.bat
start voter.bat
pause