`
liufei.fir
  • 浏览: 693777 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

获取客户机IP地址

阅读更多
package org.liufei.jweb;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

/**
 * 向指定的137端口发出固定格式的查询命令,返回结果中即含有客户端mac地址
 * 
 * @author liufei
 * 
 */
public class UDPGetClientMac {
	private String remote_address;
	private static final int REMOTE_PORT = 137;
	private static final byte[] BUFFER = new byte[1024];
	private DatagramSocket datagram_socket = null;

	public static void main(String[] args) throws SocketException, IOException {
		System.out.println(UDPGetClientMac.getRemoteHostMacAddress("172.16.0.11"));
	}

	public static String getRemoteHostMacAddress(String address) throws SocketException, IOException {
		return new UDPGetClientMac(address).getRemoteHostMacAddress() ;
	}
	
	private UDPGetClientMac(String address) throws SocketException {
		remote_address = address;
		datagram_socket = new DatagramSocket();
	}

	private final DatagramPacket send(final byte[] bytes) throws IOException {
		DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, InetAddress
				.getByName(remote_address), REMOTE_PORT);
		datagram_socket.send(datagramPacket);
		return datagramPacket;
	}

	private final DatagramPacket receive() throws IOException {
		DatagramPacket datagramPacket = new DatagramPacket(BUFFER, BUFFER.length);
		datagram_socket.receive(datagramPacket);
		return datagramPacket;
	}
	
	/**
	 * 询问包结构:
	 * Transaction ID 两字节(16位) 0x00 0x00
	 * Flags 两字节(16位) 0x00 0x10
	 * Questions 两字节(16位) 0x00 0x01
	 * AnswerRRs 两字节(16位) 0x00 0x00
	 * AuthorityRRs 两字节(16位) 0x00 0x00
	 * AdditionalRRs 两字节(16位) 0x00 0x00
	 * Name:array [12..45] 0x20 0x43 0x4B 0x41(30个) 0x00 ;
	 * Type:NBSTAT 两字节 0x00 0x21
	 * Class:INET 两字节(16位)0x00 0x01
	 * 
	 * @return
	 * @throws Exception
	 */
	private final byte[] queryCmd() {
		byte[] t_ns = new byte[50];
		t_ns[0] = 0x00;// transaction[0]
		t_ns[1] = 0x00;// transaction[1]
		t_ns[2] = 0x00;// flags[0]
		t_ns[3] = 0x10;// flags[1]
		t_ns[4] = 0x00;// questions[0]
		t_ns[5] = 0x01;// questions[1]
		t_ns[6] = 0x00;
		t_ns[7] = 0x00;
		t_ns[8] = 0x00;
		t_ns[9] = 0x00;
		t_ns[10] = 0x00;
		t_ns[11] = 0x00;
		t_ns[12] = 0x20;
		t_ns[13] = 0x43;
		t_ns[14] = 0x4B;

		for (int i = 15; i < 45; i++) {
			t_ns[i] = 0x41;
		}

		t_ns[45] = 0x00;
		t_ns[46] = 0x00;// nbstat
		t_ns[47] = 0x21;// nbstat
		t_ns[48] = 0x00;
		t_ns[49] = 0x01;
		return t_ns;
	}

	/**
	 * 表1 “UDP-NetBIOS-NS”应答包的结构及主要字段一览表
	 * 序号 字段名 长度
	 * 1 Transaction ID 两字节(16位)
	 * 2 Flags 两字节(16位)
	 * 3 Questions 两字节(16位)
	 * 4 AnswerRRs 两字节(16位)
	 * 5 AuthorityRRs 两字节(16位)
	 * 6 AdditionalRRs 两字节(16位)
	 * 7 Name<Workstation/Redirector> 34字节(272位)
	 * 8 Type:NBSTAT 两字节(16位)
	 * 9 Class:INET 两字节(16位)
	 * 10 Time To Live 四字节(32位)
	 * 11 Length 两字节(16位)
	 * 12 Number of name 一个字节(8位),名字长度---56
	 * NetBIOS Name Info 18×Number Of Name字节--占 这么多的字节
	 * Unit ID 6字节(48位)-->接下来就是mac地址
	 * 
	 * @param brevdata
	 * @return
	 * @throws Exception
	 */
	private final String getHostMacAddress(byte[] brevdata) {
		int i = brevdata[56] * 18 + 56;
		String address = "";
		StringBuffer result = new StringBuffer(17);

		for (int j = 1; j < 7; j++) {
			address = Integer.toHexString(0xFF & brevdata[i + j]);
			if (address.length() < 2) {
				result.append(0);
			}
			result.append(address.toUpperCase());
			if (j < 6) {
				result.append(':');
			}
		}
		return result.toString();
	}

	private final void close() {
		if(datagram_socket != null) {
			datagram_socket.disconnect() ;
			datagram_socket.close() ;
		}
	}

	private final String getRemoteHostMacAddress() throws IOException {
		byte[] cmd_byte = this.queryCmd();
		this.send(cmd_byte);
		DatagramPacket datagramPacket = this.receive();
		String smac = this.getHostMacAddress(datagramPacket.getData());
		this.close();
		return smac;
	}
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics