- 说明问题
如果我们要监控TCP协议的端口,那么比较简单。只要通过 telnet ip port,就可以查看端口是否处于正常状态。因为TCP的协议是应答式的,也就是说,从发请请求到结束,TCP会跟踪最后的结果是怎样,这个对于重要信息的发送是较为重要的。但是,如果要我们去监听UDP的端口,那就麻烦了,我们不能用telnet的命令,当然网站上也给出了一些在linux和windows上分别使用的命令去ping UDP,但是在windows上极为麻烦。因为UDP协议只管发送消息,不管消息是否已经送达。换句话为,UDP只将消息发送出去后,为没下文了,消息是怎样的,它已经不管了,所以我们很难监听UDP的端口情况。笔者用了一天的时间查找了所有的资料,关于如何用java代码去实现ping一个UDP的端口,后来发现没有办法可以实现,如里读者有好的方法,希望可以留言。
- 解决方法
上面笔者已经说了,无法直接去监听UDP的端口,准确的说是无法去ping UDP的端口,既然无法ping,那么我们是否可以监听UDP的端口?可以的话用什么方法来监听?
我们知道,在windows的DOC命令中,我们用netstatus –ano,可看到所有的端口,包括UDP和TCP。既然这样的话,那么监听UDP的端口应该是可以的。那么还有问题就来了,我们是用Java的代码 Runtime来直接 去行netstauts –ano的命令获取信息后再筛选,还是说有其它方法呢?当然是用其它的方法,用Runtime有点麻烦,这里笔者用的是snmp的协议去获取所有端口,注意只获取端口,然后筛选出自己要监听的UDP端口。
- 实现方法
首先,电脑需要开启snmp的协议(笔者将会写一篇关于如果开启snmp的博客)。配置好团体名称。
其次,需要下载snmp4j.jar的包。
最后,通过java的代码来实现,下面只是笔者写的一个测试类,因此不完善,运行可能会没有结果,请谅解。代码如下:
package com.owen.blog.udp.snmp;
import java.io.IOException;
import java.util.List;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.Target;
import org.snmp4j.TransportMapping;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.PDUFactory;
import org.snmp4j.util.TableUtils;
/**
*
* @author owen william
* @Date 2018-08-24
*
*/
public class UDPPortInfos implements PDUFactory
{
@Override
public PDU createPDU(Target arg0) {
PDU request = new PDU();
request.setType(PDU.GET);
return request;
}
/**
* 获取需要的端口信息
*
* @param ipAddress 地址
* @param community 团体名
* @return
* @throws IOException
*/
public List createTable(String ipAddress, String community) throws IOException {
Target t = createTarget(ipAddress, community);
TransportMapping tm = new DefaultUdpTransportMapping();
Snmp snmp = new Snmp(tm);
TableUtils tu = new TableUtils(snmp, this);
OID[] columns = new OID[1];
columns[0]= new OID("1.3.6.1.2.1.1.5.0");
List list = tu.getTable(t, columns, null, null);//获取数据
return list;
}
/**
* 创建连接信息
*
* @param ipAddress 地址
* @param community 团体名
* @return
*/
public CommunityTarget createTarget(String ipAddress, String community) {
CommunityTarget t = new CommunityTarget();
t.setCommunity(new OctetString(community)); //团体名
t.setVersion(0); //版本
t.setRetries(1); //重试次数
t.setAddress(GenericAddress.parse("127.0.0.1/161")); //地址
t.setTimeout(5000); //超时时间
return t;
}
/**
* 测试--不会有结果
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
UDPPortInfos upi = new UDPPortInfos();
String[][] tableContent = null;
List ports = upi.createTable("127.0.0.1","owen");
}
}