基础知识
1.InetAddress类
在网络API套接字,InetAddress类和它的子类型对象使用域名DNS系统,处理主机名到主机IPv4或IPv6地址的转换。如图1-1所示。
由于InetAddress类只有一个构造函数,且不能传递参数,所以不能直接创建该对象实例,比如下面的做法就是错误的:
InetAddress ia = new InetAddress (); × |
可通过以下5个成员方法获得InetAddress对象或InetAddress数组:
l getAllByName(String host)方法返回一个InetAddress对象的引用,每个对象包含一个表示相应主机名的单独的IP地址,这个IP地址是通过host参数传递的,例如:
InetAddress [] ia = getAllByName(“MyHost”); |
l getByAddress(byte [] addr)方法返回一个InetAddress对象的引用,这个对象包含了一个Ipv4地址或Ipv6地址,Ipv4地址是一个4字节数组,Ipv6地址是一个16字节地址数组。
l getByAddress(String host, byte [] addr)方法返回一个InetAddress对象的引用,这个InetAddress对象包含了一个由host和4字节的addr数组指定的IP地址,或者是host和16字节的addr数组指定的IP地址。
l getByName(String host)方法返回一个InetAddress对象,该对象包含了一个与host参数指定的主机相对应的IP地址。
l getLocalHost()方法返回一个InetAddress对象,这个对象包含了本地机的IP地址。
以上各方法均可能产生的UnknownHostException(未知的主机名)异常。当获得了InetAddress类对象的引用就可以调用InetAddress的各种方法来获得InetAddress子类对象中的IP地址信息。例,通过调用getCanonicalHostName()从域名服务中获得标准的主机名,getHostAddress()获得IP地址,getHostName()获得主机名,isLoopbackAddress()判断IP地址是否是一个loopback环回地址。
2.URL类
IP地址唯一标识了Internet上的计算机,而URL则标识了这些计算机上的资源。通常,URL是一个包含了传输协议、主机名称、服务端口号、文件路径名称,以及间隔符号“://”、“:”、“/” 等信息的字符串,例:https://www.cnblogs.com/ftl1012/p/9346858.html
为了方便程序员编程,JDK中提供了URL类,该类的全名是java.net.URL,该类用于使用它的各种方法来对URL对象进行分割、合并等处理,如图1-2所示。
URL有6种构造方法,通常使用了绝对URL路径构造方法,其中的URL参数是一个完整的URL字符串,而且必须要包含传输协议,如:
URL raceHtml=new URL("https://www.cnblogs.com/ftl1012/p/9346858.html"); |
四、常用方法
1. InetAddress类主要方法
byte[] |
getAddress() 返回该对象的原始IP。 |
static InetAddress[] |
getAllByName(String host) 获得指定主机域名的所有IP地址。 |
static InetAddress |
getByAddress(byte[] addr) 获得指定IP地址对象。 |
static InetAddress |
getByAddress(String host, byte[] addr) 根据指定主机名和IP地址创建对象。 |
static InetAddress |
getByName(String host) 根据指定主机名获得对象。 |
String |
getCanonicalHostName() 获得指定域名的法定信息。 |
String |
getHostAddress() 返回当前IP地址字符串。 |
String |
getHostName() 获得当前IP地址的主机名。 |
static InetAddress |
getLocalHost() 获得本地主机。 |
boolean |
isLoopbackAddress() 判断IP是否为环回地址。 |
2. URL类主要方法
getAuthority() 获得URL的认证部分。 |
|
getContent() 获得URL的内容。 |
|
getContent(Class[] classes) 获得URL的内容 |
|
int |
getDefaultPort()获得URL默认的端口号 |
getFile() 获得URL的文件名 |
|
getHost()获得该URL的主机名 |
|
getPath() 获得该URL的路径 |
|
int |
getPort() 获得该URL的端口 |
getProtocol()获得该URL的协议。 |
|
getQuery()获得该URL的查询部分 |
|
getRef()获得该URL的锚部分 |
|
getUserInfo()获得该URL的用户信息 |
|
openConnection() 返回URL的连接。 |
|
openStream()打开URL的输入读取流 |
代码示例
根据主机名查找IP
1 import java.net.InetAddress; 2 import java.util.*; 3 4 public class My 5 { 6 public static void main(String[] args) 7 { 8 String local = null ; 9 for(int i =18;i<20;i++){ 10 local = "FF109Lx-"+i ; 11 try{ 12 InetAddress inet = InetAddress.getByName(local) ; 13 byte[] ip = inet.getAddress(); 14 System.out.print("FF109Lx-"+i); 15 for(int x=0;x<ip.length;x++){ 16 int ips = (ip[x]>=0?ip[x]:(ip[x]+256)) ; 17 System.out.print(" "+ips+"." ) ; 18 } 19 }catch(Exception e ){ 20 System.err.println("FF109Lx-"+i+" 获得本地信息失败..." ); 21 System.out.println(); 22 } 23 } 24 } 25 }
根据IP查找主机
1 package com.hhh.ftl; 2 import java.net.InetAddress; 3 import java.util.*; 4 5 public class Test 6 { 7 public static void main(String[] args) 8 { 9 String local = null ; 10 for(int i =100;i<102;i++){ 11 local = "192.168.1."+i ; 12 try{ 13 InetAddress inet = InetAddress.getByName(local) ; 14 byte[] ip = inet.getAddress(); 15 System.out.print("FF109Lx-"+i); 16 for(int x=0;x<ip.length;x++){ 17 int ips = (ip[x]>=0?ip[x]:(ip[x]+256)) ; 18 System.out.print(" "+ips+"." ) ; 19 } 20 System.out.println(""); 21 }catch(Exception e ){ 22 System.err.println("FF109Lx-"+i+" 获得本地信息失败..." ); 23 } 24 } 25 } 26 }
采用多线程方式探测某主机上所有的TCP端口开放情况
1 package com.hhh.ftl; 2 3 import java.net.*; 4 import java.io.*; 5 import java.net.*; 6 7 class Sum { // 共享资源,计数器count 8 private int count;// 共享资源 9 10 public int add() { 11 synchronized (this) { // 代码段1,共享锁,修饰程序段或者方法 12 count = count + 1; 13 System.out.println("add:" + count); 14 return count; 15 } 16 } 17 } 18 19 class ScanThread implements Runnable {// 定义线程 20 private Sum sd; 21 private int sum = 0; 22 private String host; 23 24 public ScanThread(String name, Sum sd, String host) { 25 this.sd = sd; 26 this.host = host; 27 } 28 29 public void run() {// 必需的重写 30 int port; 31 try { 32 for (int i = 0; i < 65535; i++) { 33 port = sd.add(); 34 if (port > 65535) 35 break; 36 try { 37 Socket cs = new Socket(host, port); 38 System.out.println("port" + port + "出于开放状态"); 39 cs.close(); 40 } catch (Exception e) { 41 System.err.println("port" + port + "不能连接"); 42 } 43 Thread.sleep(100); 44 } 45 Thread.sleep(1000); 46 } catch (Exception e) { 47 System.err.println("sleep异常"); 48 } 49 } 50 } 51 52 public class ScanD1emo { 53 public static void main(String[] args) { 54 Sum sd = new Sum();// 代表共享资源的变量 55 ScanThread s1 = new ScanThread("线程1", sd, "localhost");// 创建完毕 56 ScanThread s2 = new ScanThread("线程2", sd, "localhost"); 57 ScanThread s3 = new ScanThread("线程3", sd, "localhost"); 58 Thread st1 = new Thread(s1); 59 Thread st2 = new Thread(s2); 60 Thread st3 = new Thread(s3); 61 try { 62 long begin = System.currentTimeMillis(); 63 st1.start();// 使线程运行 64 st2.start(); 65 st3.start(); 66 67 st1.join(); 68 st2.join(); 69 st3.join(); 70 long end = System.currentTimeMillis(); 71 System.out.println("探测localhost的TCP端口,共耗时" + (end - begin) + "毫秒"); 72 } catch (Exception e) { 73 System.err.println(e.getMessage()); 74 } 75 } 76 }
使用InetAddress类,用于获得指定的计算机名称和IP地址
View Code
采用了URL类,用于解析在单行编辑框中输入的URL地址,分解出访问协议、主机名称、端口号以及文件路径名称等。
1 package com.hhh.ftl; 2 import java.net.URL; 3 import java.net.MalformedURLException; 4 public class myURL{ 5 URL url; 6 public myURL(String urlStr){ 7 try{ 8 url = new URL(urlStr); 9 }catch(Exception e){ 10 System.err.println(e.getMessage()); 11 } 12 } 13 public void resolve(){ 14 System.out.println(url.getProtocol()); 15 System.out.println(url.getHost()); 16 System.out.println(url.getPort()); 17 System.out.println(url.getPath()); 18 System.out.println(url.getFile()); 19 System.out.println(url.getQuery()); 20 System.out.println(url.getRef()); 21 } 22 public static void main(String [] args){ 23 myURL my = new myURL("https://www.cnblogs.com/ftl1012/p/9346858.html"); 24 my.resolve(); 25 } 26 }
图形化的URL输入和分析
1 package com.hhh.ftl; 2 import java.net.URL; 3 import java.net.MalformedURLException; 4 import java.awt.*; 5 import java.awt.event.*; 6 public class getURLInformation extends Frame{ 7 TextField tUrl = new TextField("输入URL地址"); 8 List lItems = new List(20); 9 Button bOk = new Button("解 析"); 10 Font f = new Font("Serif",Font.BOLD,30); 11 public getURLInformation(){ 12 this.setLayout(new BorderLayout()); 13 this.add(tUrl, BorderLayout.NORTH); 14 this.add(lItems, BorderLayout.CENTER); 15 this.add(bOk, BorderLayout.SOUTH); 16 tUrl.setFont(f); 17 lItems.setFont(f); 18 bOk.setFont(f); 19 addWindowListener(new WindowAdapter() { 20 public void windowClosing(WindowEvent e) { 21 dispose(); 22 System.exit(0); 23 } 24 }); 25 bOk.addActionListener(new Listener()); 26 } 27 public static void main(String args[]){ 28 System.out.println("Starting New..."); 29 getURLInformation mainFrame = new getURLInformation(); 30 mainFrame.setSize(400, 400); 31 mainFrame.setTitle("解析URL"); 32 mainFrame.setVisible(true); 33 } 34 class Listener implements ActionListener{ 35 public void actionPerformed(ActionEvent e){ 36 URL getURL = null; 37 38 try{ 39 getURL = new URL(tUrl.getText()); 40 }catch(MalformedURLException e1){ 41 System.out.println("URL解析错误" + e1); 42 } 43 lItems.add("Reference:" + getURL.getRef(), 0); 44 lItems.add("File Name:" + getURL.getFile(), 0); 45 lItems.add("File Path:" + getURL.getPath(), 0); 46 lItems.add("Host Port:" + getURL.getPort(), 0); 47 lItems.add("Host Name:" + getURL.getHost(), 0); 48 lItems.add("Protocol :" + getURL.getProtocol(), 0); 49 } } }
通过URL获得网页上文本资源
1 package com.hhh.ftl; 2 import java.io.*; 3 import java.net.*; 4 public class Test{ 5 public static void main(String [] args) throws Exception{ 6 String url = "https://www.cnblogs.com/ftl1012/p/9346858.html"; //自行输入URL,例如https://www.cnblogs.com/ftl1012/p/9346858.html; 7 InputStream in = (new URL(url)).openStream(); //获得指定URL的字节输入流 8 int c = -1; 9 while((c = in.read()) != -1){ //按字节的方式输入数据和输出数据 10 System.out.write(c); 11 } } }
通过URL获得网页上图像资源
1 import java.io.*; 2 import java.net.*; 3 class exp_4_8{ 4 public static void main(String [] args){ 5 try{ 6 InputStream imageSource = new URL(网络图片的URL).openStream(); 7 FileOutputStream myFile = new FileOutputStream("c://myLogo.gif"); 8 BufferedOutputStream myBuffer = new BufferedOutputStream(myFile); 9 DataOutputStream myData = new DataOutputStream(myBuffer); 10 int ch; 11 while((ch = imageSource.read()) > -1){ //由网络输入数据 12 myData.write(ch); //将数据输出到文件中 13 } 14 myBuffer.flush(); //将文件缓存中数据写入文件 15 imageSource.close(); 16 myFile.close(); 17 myBuffer.close(); 18 myData.close(); 19 }catch(Exception e){ 20 System.err.print(e.toString()); 21 } } }
获得JVM系统信息,记录在当前运行该程序的JVM信息
View Code
利用URL类型实现从指定地址获得文本格式的HTML源文件
View Code
实现利用InetAddress.getByName()按计算机名称获得实验室局域网中所有开机主机名称和IP地址
View Code
实现利用InetAddress.getByName()按IP地址获得指定网络段所有开机主机名称/域名和IP地址
1 package com.mc.test1; 2 3 import java.io.BufferedReader; 4 import java.io.InputStreamReader; 5 import java.net.*; 6 public class Main { 7 8 public static void main(String[] args) throws Exception { 9 10 11 System.out.println(" "+"------------------------------------------"); 12 System.out.println("PIng时间为2秒") ; 13 for(int i=18;i<30;i++){ 14 String local = "FF109Lx-"+i ; 15 try{ 16 InetAddress inet = InetAddress.getByName(local); 17 System.out.println(inet); 18 System.out.println("局域网内的主机名称:"+inet.getHostName()); //获得主机名称 19 byte [] ip = inet.getAddress(); //获得主机IP地址 20 for(int x=0;x<ip.length;x++){ 21 int ips = (ip[x] >=0) ? ip[x] : (ip[i] + 256); //将byte数值转换为int数值 22 System.out.print(ips + "."); 23 } 24 inet.isReachable(2000) ; 25 }catch(Exception e){ 26 System.err.println("获得信息失败" + e.toString()); 27 } 28 } 29 30 31 32 33 } 34 }
实现1-30的累计,其中共享资源池为1-30的数字的递增,采用了同步锁synchronized【待修改】
1 class Sum{ //共享资源,计数器count 2 private int count;//共享资源 3 public int add(){ 4 synchronized(this){ //代码段1,共享锁,修饰程序段或者方法 5 count = count + 1; 6 System.out.println("add:" + count); 7 return count; 8 } 9 } 10 } 11 class SumThread implements Runnable{//定义线程 12 private Sum sd; 13 private int sum = 0; 14 private int [] a = new int[10]; 15 16 public SumThread(String name, Sum sd){ 17 super(name); 18 this.sd = sd; 19 } 20 public void run(){//必需的重写 21 try{ 22 for(int i=0;i<10;i++){ 23 a[i] = sd.add(); 24 sum += a[i]; 25 Thread.sleep(100); 26 } 27 Thread.sleep(1000); 28 }catch(Exception e){} 29 30 System.out.println(getName() + "累加和:" + sum); 31 } 32 public void showData(){ 33 System.out.print(getName() + "获得的数为"); 34 for(int i=0;i<10;i++){ 35 if(i%10==0)System.out.println(); 36 System.out.print(a[i] + "+ "); 37 } 38 } 39 public int getSum(){ 40 return sum; 41 } 42 } 43 public class SumDemo{ 44 public static void main(String [] args){ 45 Sum sd = new Sum();//代表共享资源的变量 46 SumThread s1 = new SumThread("线程1",sd);//创建完毕 47 SumThread s2 = new SumThread("线程2",sd); 48 SumThread s3 = new SumThread("线程3",sd); 49 Thread st1 = new Thread(s1); 50 Thread st2 = new Thread(s2); 51 Thread st3 = new Thread(s3); 52 st1.setPriority(Thread.MAX_PRIORITY); //代码段2 53 st2.setPriority(10); 54 st3.setPriority(1); 55 long begin = System.currentTimeMillis(); 56 st1.start();//使线程运行 57 st2.start(); st3.start(); 58 St1.join(); st2.join(); st3.join(); 59 st1.showData(); 60 st2.showData(); 61 st3.showData(); 62 System.out.println("总和为:" + (st1.getSum() + st2.getSum() + st3.getSum())); 63 long end = System.currentTimeMillis(); 64 System.out.println(“探测localhost的TCP端口,共耗时” + 65 ( end - begin)+"毫秒"); 66 } }