目的:
某现场设备厂家通过snmp协议发送告警到网管侧设备上,网管snmp采集程序接收不到告警,通过抓包命令能看到网卡上有告警,snmp协议版本为V2.
1)从网卡上抓包日志中读取二进制内容发送到某机器端口;
2)通过Udp接收程序从机器端口接收告警;
接收端代码
package com.udp;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* UDP接收
*
* 可用下面方式运行到Unxi/Linux环境
* a)程序目录情况
* udptest
* |--start.sh
* |--udpreceive.jar
* b)程序启停
* 启动 ./start.sh
* 停止 ps -ef | grep "program.name=UdpReceiver"|grep -v grep|awk '{print $2}'|xargs -i kill -9 {}
* c)脚本start.sh内容如下
#!/bin/sh
JARS="./udpreceive.jar"
export JARS
lintenPort=1622
nohup java -Dprogram.name=UdpReceiver -Dfile.encoding=GBK -cp $JARS com.boco.util.UdpReceiver $lintenPort &
*
* @author DAL.feng
*
*/
public class UdpReceiver {
public static final int DEFAULT_LINSTEN_PORT = 1622;
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static String home = "";
public static void main(String[] args) {
System.out.println("UdpReceiver is start ...");
receive(args);
System.out.println("UdpReceiver is end!");
}
private static void receive(String[] args) {
int linstenPort = init(args);
System.out.println("linstening port : " + linstenPort);
try {
DatagramSocket udp = new DatagramSocket(linstenPort);
udp.setSoTimeout(10);
boolean isRun = true;
long count = 1;
while(isRun) {
work(udp, count);
count ++;
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 启动参数第一个是udp接收的监听端口
* @param args
* @return
*/
private static int init(String[] args) {
if(args == null || args.length < 1) {
return DEFAULT_LINSTEN_PORT;
}
return Integer.parseInt(args[0].trim());
}
/**
* 循环内的一次执行动作;
* @param udp
* @param count 动作执行次数
*/
private static void work(DatagramSocket udp, long count) {
try {
DatagramPacket packet = receive0(udp);
if(packet == null) {
if(count % 6 == 1) {
System.out.println(sdf.format(new Date()) + " --- no data");
}
Thread.sleep(1000);
} else {
byte[] receiveData = packet.getData();
int dataLength = packet.getLength();
String result = new String(receiveData, 0, dataLength);
result = result.trim();
System.out.println("receive length:" + packet.getLength());
if(result.length() > 0) {
System.out.println("receive data:" + result);
}
saveFile(receiveData, dataLength);
packet = null;
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 从监听端口读取数据,有超时设置,默认10ms,如果无数据则返回null
* @param udp
* @return
*/
private static DatagramPacket receive0(DatagramSocket udp) {
byte[] buf = new byte[10240];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
try {
udp.receive(packet);
} catch (Exception e) {
// e.printStackTrace();
packet = null;
}
return packet;
}
private static void saveFile(byte[] result, int length) {
String filepath = getHome() + System.currentTimeMillis() + ".data";
try {
FileOutputStream f = new FileOutputStream(filepath);
f.write(result, 0, length);
f.flush();
System.out.println("save file: " + filepath);
f.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static String getHome() {
if(home == null || "".equals(home)) {
File f = new File("");
String home0 = f.getAbsolutePath();
System.out.println(home0);
home = home0.endsWith("/") ? home0 : home0+"/";
}
return home;
}
}
从文件读取二进制内容发送到Udp端口
package com.udp;
import java.io.FileInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import junit.framework.TestCase;
public class UdpLiteTest extends TestCase {
protected void setUp() throws Exception {
super.setUp();
}
public void testSendUdpLite() {
String targetHost = "10.10.1.162";
// String targetHost = "127.0.0.1";
int targetPort = 1625;
try {
// 初始化udp,采用随机端口
DatagramSocket udp = new DatagramSocket();
// 初始化数据包,里面包含了数据byte[],目的地址,和目的端口,数据发送到哪,完全由数据包中目的地址和端口决定
DatagramPacket data = new DatagramPacket(new byte[0], 0, InetAddress.getByName(targetHost), targetPort);
// 读数据
data.setData(readSnmpData());
// 读心跳
// data.setData(readSnmpHeart());
// data.setData(readSnmpClient());
// 读其他模拟程序发的snmp内容,这个是一个完整的snmp样例
data.setData(readSnmpRealLong());
udp.send(data);
System.out.println("send finish");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private byte[] readSnmpData() {
String snoopResultPath = "d:/03-Run/snmp/1009-1";
// int snmpLength = 2783;
int snmpLength = 1472;
int start = 0x850 + 10;
return readSnmp0(snoopResultPath, snmpLength, start);
}
private byte[] readSnmpHeart() {
String snoopResultPath = "d:/03-Run/snmp/1009-1";
int snmpLength = 187;
int start = 0x650 + 10;
return readSnmp0(snoopResultPath, snmpLength, start);
}
private byte[] readSnmpClient() {
String snoopResultPath = "d:/03-Run/snmp/soo7";
int snmpLength = 1176;
int start = 0x50 + 2;
return readSnmp0(snoopResultPath, snmpLength, start);
}
private byte[] readSnmpRealLong() {
String snoopResultPath = "d:/03-Run/snmp/1622-2.pcap";
int snmpLength = 3041;
int start = 0x50 + 2;
return readSnmp0(snoopResultPath, snmpLength, start);
}
private byte[] readSnmp0(String snoopFilepath, int readLength, int startIndex) {
String snoopResultPath = snoopFilepath;
int snmpLength = readLength;
int start = startIndex;
byte[] content = new byte[snmpLength];
try {
FileInputStream is = new FileInputStream(snoopResultPath);
// 先将起始位置之前的字节给去掉
is.skip(start);
is.read(content, 0, snmpLength);
System.out.println("------ content:" + new String(content));
// content = "ssss".getBytes();
is.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return content;
}
}
附件列表