java 做多线程通讯

前几天老大给我一个任务,要求我用java做一个发送端,模拟一个双IP终端向定时间间隔向两台服务器发送登录指令,根据服务器是否有回馈来判断服务器软件是否异常关闭。

1、每隔3分钟发送一次登录,这个肯定是多线程,要做两个线程,分别向两天服务器发送登录,然后立马将UDP接口转换成接收状态,但是转换之后,如果收到数据,可以顺利执行下面代码;如果没有收到数据,会一直处于接收状态,进入阻塞,后续的关闭UDP通道的指令也不能执行。因为这个必须3分钟一次登录,我只能在每次收到(或者是没收到)数据就及时将连接socket关闭,否则下次新建UDP socket的时候会报异常,这也是这个问题的根结(UDP socket 阻塞了)。。。

2、整个程序的布置就是要将向多个IP发送登录、接收回馈、报警、写日志等一系列动作放在线程中执行,IP、端口、数据包等信息均放在配置文件中读取。

模块设计:

1、数据字节处理

public static byte[] hex2byte(String s1)//输入为16进制字符串,转换成byte字节
	{
		String digital = "0123456789ABCDEF";
		char[] hex2char = s1.toCharArray();
		byte[] bytes = new byte[s1.length() / 2];
		int temp;
		for (int i = 0; i < bytes.length; i++) {
			temp = digital.indexOf(hex2char[2 * i]) * 16;
			temp += digital.indexOf(hex2char[2 * i + 1]);
			bytes[i] = (byte) (temp & 0xff);
		}
		return bytes;
	}

2、建立UDP socket

发送与接收都用同一个端口,这对UDP通信来说是比较复杂的,原因有两点:其一、UDP通信是面向无连接的,服务端的代码只负责接收数据,监听固定端口,而客户端,在建立socket通道的时候就可以指定本地端口(也可不指定,此时客户端操作系统随机指定端口),在发送时,监控软件处于客户端;在接收时,监控软件处于服务端。如果要使程序死循环执行下去,每隔3分钟发送一个登录包,即每三分钟进行一次客户端和服务端的切换。其二、UDP的receive方法是阻塞函数(这个我要做下解释,阻塞即意味着,在阻塞发生时,程序停留在这个地方,其后面的代码不执行),当然,这个可以通过设置socket的timeout值来迫使阻塞破裂,进而执行catch (IOException e) {...}里面的代码,这个对于多进程死循环程序很重要。

3、多线程执行代码处理与共享内存管理

多线程对内存共享是一种很重要的技术,这对于处理多任务时至关重要,因为对变量的修改要加锁,所以将变量多线程执行段放在synchronized中执行,例如

synchronized (this) {
				frame.appendString("\r\n <== Receive data from "+datagramPacket.getAddress().toString());
			}
这样,在frame中显示的内容就直接根据当前进程显示内容滚动显示。

4、读入配置文件(文本文件与声音文件)

读配置文件是很关键的一步,一直纠结与编译前和编译后,对相对路径的迷惑,我一般采用指定绝对路径的方法,说不定哪天能够意外发现大牛的某篇博客而茅塞顿开,在就不谈路径问题。

一度面临先有鸡先有蛋的问题迷惑不已,软件执行--读配置文件--加载配置文件--执行输出。这似乎成了小程序的固定模式,当然,也可以在读配置文件之前,通过UI来给用户自定义配置文件路径,这样似乎也有点不科学,软件如果都做的这么傻瓜了,你的软件就肯定会贬值,当然也会获得很好的用户体验。

	public void Alert(String alert_file_path) {//读声音文件
		try {
			 FileInputStream fileau=new  FileInputStream(alert_file_path);
			 AudioStream as=new AudioStream(fileau);
			 AudioPlayer.player.start(as);
			} catch (IOException e) {
				e.printStackTrace();
           }
	}

配置文件中要加载很多台服务器的IP地址、端口,本地端口,发送数据字节(0x),这些数据我还是推荐用数组来处理,而且,安全性更高,如果我给用户的最大值为1billion,是否可以认为,用户将拿我的软件对GPS运营商进行暴力攻击?

5、写日志文件

写日志文件对很多人来说都不值得提,因为太多的博客在教我们read & write log files,这里不再复述。

6、动态信息打印

动态信息打印的基础是你先画出一个frame,这个可以参看某些基础教材,本人比较喜欢看大学教材,虽然过于简单,但是确实看完印象深刻。

7、主函数

主函数的设计是对整个软件运行流程的把握,下面直接上代码

public static void main(String[] args){
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (InstantiationException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IllegalAccessException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (UnsupportedLookAndFeelException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		frame=new DragingFrame();
        frame.setSize(400, 300);
        frame.setLocation(300, 300);
        frame.setResizable(false);
        
        frame.setTitle("服务端监控程序  developed by forilen V1.3");
        frame.setVisible(true);
        
//		JOptionPane.showMessageDialog(null, "程序已经打开,切勿重复打开!");
		readFile rf=new readFile();
		String [][]config;
		config =rf.readFileByLines("C:/alter_info/alter.conf");//Read the configure text(IP,port,packages) from the file
		int timeout=Integer.parseInt(config[0][0]);
		int frequency=Integer.parseInt(config[0][1]);
		int auto=Integer.parseInt(config[0][2]);
		int total=Integer.parseInt(config[0][3])+1;
		
		while (flag) {//根据flag配置文件,设置参数是否死循环执行
			for (int i = 1; i < total; i++) {
				test_so r1 = new test_so("1s");
				r1.set_tag(config[i][0], config[i][1], config[i][2],timeout,config[i][3]);
				Thread t1 = new Thread(r1, "t1");
				t1.start();
			}
			try {
				Thread.sleep(frequency*1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (auto==0) {
				continue;
			}
			else {
				auto--;
				if (auto==0) {
					break;
				}
			}
		}
    }

8、程序发布

程序发布我还是建议直接发布成jar包就行了,exe文件运行都太过肤浅,装了jre的机子都支持jar包的执行



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值