雖然以下 PL/SQL Code 可以取得, 可是在 3-Tier 架構下, 取到的都是 AP 的 IP 與 Host Name, 不是最終用戶端的資料
DECLARE
IP_ADDRESS VARCHAR2(50);
HOSTNAME VARCHAR2(50);
BEGIN
IP_ADDRESS := UTL_INADDR.GET_HOST_ADDRESS(); --得到ip
HOSTNAME := UTL_INADDR.GET_HOST_NAME(); --得到機器名
DBMS_OUTPUT.PUT_LINE(IP_ADDRESS);
DBMS_OUTPUT.PUT_LINE(HOSTNAME);
END;
不過 Oracle Metalink 上有一篇文章 "How to Get the Physical IP Address of the Client Machine [ID 853971.1]", 我沒試過, 有需要的人可以參考參考
Solution
The Physical IP Address is also known as MAC Address or MAC ID or Hardware Address. This can be achieved with a java program which can be implemented via a Forms PJC.
Create the Java Bean
1. Create a Java file "getMacAddress.java" as follows say in d:\pjc folder
import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.net.InetAddress; import java.net.UnknownHostException; import oracle.forms.ui.*; import oracle.forms.properties.*; public class getMacAddress extends VBean { public getMacAddress() { System.out.println("Bean has been initialised"); } /* public static void main(String[] args) { String res = getAddress(); System.out.println(res); } */ public String getAddress() { String macAddress = null; String getAddress = null; Process p = null; BufferedReader in = null; try { String osname = System.getProperty("os.name"); if (osname.startsWith("Windows")) { p = Runtime.getRuntime().exec( new String[] { "ipconfig", "/all" }, null); } // Solaris code must appear before the generic code else if (osname.startsWith("Solaris") || osname.startsWith("SunOS")) { String hostName = getFirstLineOfCommand(new String[] { "uname", "-n" }); if (hostName != null) { p = Runtime.getRuntime().exec( new String[] { "/usr/sbin/arp", hostName }, null); } } else if (new File("/usr/sbin/lanscan").exists()) { p = Runtime.getRuntime().exec( new String[] { "/usr/sbin/lanscan" }, null); } else if (new File("/sbin/ifconfig").exists()) { p = Runtime.getRuntime().exec( new String[] { "/sbin/ifconfig", "-a" }, null); } if (p != null) { in = new BufferedReader(new InputStreamReader( p.getInputStream()), 128); String l = null; while ((l = in.readLine()) != null) { macAddress = parse(l); if (macAddress != null && parseShort(macAddress) != 0xff) break; } } } catch(IOException e) { e.printStackTrace(); } catch(Exception e) { e.printStackTrace(); } return macAddress; } public String parse(String in) { int hexStart = in.indexOf("0x"); if (hexStart != -1 && in.indexOf("ETHER") != -1) { int hexEnd = in.indexOf(' ', hexStart); if (hexEnd > hexStart + 2) { return in.substring(hexStart, hexEnd); } } int octets = 0; int lastIndex, old, end; lastIndex = in.lastIndexOf('-'); if (lastIndex > in.length() - 2) return null; end = Math.min(in.length(), lastIndex + 3); ++octets; old = lastIndex; while (octets != 5 && lastIndex != -1 && lastIndex > 1) { lastIndex = in.lastIndexOf('-', --lastIndex); if (old - lastIndex == 3 || old - lastIndex == 2) { ++octets; old = lastIndex; } } if (octets == 5 && lastIndex > 1) { return in.substring(lastIndex - 2, end).trim(); } return null; } public short parseShort(String s) throws NullPointerException { s = s.toLowerCase(); short out = 0; byte shifts = 0; char c; for (int i = 0; i < s.length() && shifts < 4; i++) { c = s.charAt(i); if ((c > 47) && (c < 58)) { out <<= 4; ++shifts; out |= c - 48; } else if ((c > 96) && (c < 103)) { ++shifts; out <<= 4; out |= c - 87; } } return out; } public String getFirstLineOfCommand(String[] commands) throws IOException { Process p = null; BufferedReader reader = null; try { p = Runtime.getRuntime().exec(commands); reader = new BufferedReader(new InputStreamReader( p.getInputStream()), 128); return reader.readLine(); } finally { if (p != null) { if (reader != null) { try { reader.close(); } catch (IOException ex) {} } try { p.getErrorStream().close(); } catch (IOException ex) {} try { p.getOutputStream().close(); } catch (IOException ex) {} p.destroy(); } } } }
2. open a cmd prompt and go to d:\pjc folder(where the java file is stored) and do the following
a) set ORACLE_HOME=d:\oracle\developersuite (substitute your physical ORACLE_HOME for Developer Suite here)
b) set PATH=%ORACLE_HOME%\jdk\bin
c) set CLASSPATH=%ORACLE_HOME%\forms\java\frmall.jar;d:\pjc;%CLASSPATH%
3. Compile the above java code (getMacAddress.java) using javac
javac getMacAddress.java
4. Package getMacAddress.class into a jar file using jar.exe.
jar -cvf getMacAddress.jar getMacAddress.class
5. Sign the getMacAddress.jar file by following the instructions in Note 202768.1 Signing a Java Bean for Deployment with Forms 9i / 10g Oracle Jinitiator
using JDK 1.3
Code the Form
6. Create a simple form and add a bean area to it.
7. In the implementation class of the bean area put our class "getMacAddress"
8. Create a button with the following code in the When-Button-Pressed trigger:
declare
hbean1 item := find_item('block5.bean1');
begin
Fbean.register_bean(hbean1,1,'getMacAddress');
:text1 := Fbean.Invoke_char(hbean1,1,'getAddress');
end;
Deploy the Form with the Bean
9. Copy the getMacAddress.jar file into %ORACLE_HOME%/forms/java directory
10. Edit the formsweb.cfg from %ORACLE_HOME%/forms/server/forsweb.cfg
Add the getMacAddress.jar to the archive,archive_jini parameters in the configuration section e.g.:
[myconfig]
archive=frmall.jar,getMacAddress.jar
archive_jini=frmall_jinit.jar,getMacAddress.jar
11. Compile and run the form. This code will work with both JInitiator and JRE 1.6.0_X
Note: If the end user browser plugin is going to be JRE 1.6 + then the following, simpler, java code can be used to get the Physical address. Prior to JDK 1.6 there was no method availaable to get the hardware address of the client. However, in JDK 1.6, a new method getHardwareAddress() is available to get the hardware address. So if the JRE is going to be 1.6 or higher, then the following java source can be used
import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.UnknownHostException; import oracle.forms.ui.*; public class getMacAddress extends VBean { public String bytesText(byte in[]) { byte ch = 0x00; int i = 0; if (in == null || in.length <= 0) return null; String pseudo[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}; StringBuffer out = new StringBuffer(in.length * 2); while (i < in.length) { ch = (byte) (in[i] & 0xF0); ch = (byte) (ch >>> 4); // shift the bits down ch = (byte) (ch & 0x0F); // must do this is high order bit is on! out.append(pseudo[ (int) ch]); ch = (byte) (in[i] & 0x0F); out.append(pseudo[ (int) ch]); out.append("-"); i++; } String rslt = new String(out); return rslt.substring(0,rslt.length()-1); } public String getAddress() { String res = "none"; try { InetAddress address = InetAddress.getLocalHost(); NetworkInterface ni = NetworkInterface.getByInetAddress(address); byte[] mac = ni.getHardwareAddress(); res = bytesText(mac); } catch (UnknownHostException e) { e.printStackTrace(); } catch (SocketException e) { e.printStackTrace(); } return res; } }
References
NOTE:202768.1 - Signing a Java Bean for Deployment with Forms 9i / 10g With Oracle Jinitiator.