1. 说明问题

如果我们要监控TCP协议的端口,那么比较简单。只要通过 telnet ip port,就可以查看端口是否处于正常状态。因为TCP的协议是应答式的,也就是说,从发请请求到结束,TCP会跟踪最后的结果是怎样,这个对于重要信息的发送是较为重要的。但是,如果要我们去监听UDP的端口,那就麻烦了,我们不能用telnet的命令,当然网站上也给出了一些在linux和windows上分别使用的命令去ping UDP,但是在windows上极为麻烦。因为UDP协议只管发送消息,不管消息是否已经送达。换句话为,UDP只将消息发送出去后,为没下文了,消息是怎样的,它已经不管了,所以我们很难监听UDP的端口情况。笔者用了一天的时间查找了所有的资料,关于如何用java代码去实现ping一个UDP的端口,后来发现没有办法可以实现,如里读者有好的方法,希望可以留言。

  1. 解决方法

     上面笔者已经说了,无法直接去监听UDP的端口,准确的说是无法去ping UDP的端口,既然无法ping,那么我们是否可以监听UDP的端口?可以的话用什么方法来监听?

     我们知道,在windows的DOC命令中,我们用netstatus –ano,可看到所有的端口,包括UDP和TCP。既然这样的话,那么监听UDP的端口应该是可以的。那么还有问题就来了,我们是用Java的代码 Runtime来直接 去行netstauts –ano的命令获取信息后再筛选,还是说有其它方法呢?当然是用其它的方法,用Runtime有点麻烦,这里笔者用的是snmp的协议去获取所有端口,注意只获取端口,然后筛选出自己要监听的UDP端口。

  1. 实现方法

首先,电脑需要开启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");
	}
}