Java开发实战1200例(第二卷)学习笔记—网络应用基础
2017-08-14 14:44
501 查看
第10章网络应用基础
10.1 网络地址解析
实例297:获取本地主机的IP地址
通过InetAddress类的getLocalHost()方法获得本地主机的InetAddress对象调用该对象的getHostAddress()方法获得本地主机的IP地址。
主要代码如下:
//创建本地主机的InetAddress对象 InetAddress inetAddr=InetAddress.getLocalHost(); //获得本地主机的IP地址 String ip=inetAddr.getHostAddress();
以下摘录自Jdk 1.8谷歌翻译
public static InetAddress getLocalHost() throws UnknownHostException返回本地主机的地址。
这是通过从系统检索主机的名称,然后将该名称解析为InetAddress 。 注意:解决的地址可能会缓存一段时间。
如果有一个安全管理器,它的checkConnect方法被调用本地主机名, -1作为参数来查看是否允许该操作。
如果不允许操作,则返回表示环回地址的InetAddress。 结果 :本地主机的地址。 异常 :UnknownHostException
- 如果本地主机名无法解析成地址。
public String getHostAddress()返回文本显示中的IP地址字符串。 结果 :原始IP地址为字符串格式。 从以下版本开始: JDK1.0.2
实例298:获取本地主机的域名和主机名
通过InetAddress类的getLocalHost()方法获得本地主机的InetAddress对象调用getHostName()方法获得本地主机的名
调用getCanonicaHostName()方法获得本地主机的域名
主要代码如下:
//创建本地主机的InetAddress对象 InetAddress inetAddr=InetAddress.getLocalHost(); //获取本地主机的域名 String canonical=inetAddr.getCanonicalHostName(); //获取本地主机的主机名 String host=inetAddr.getHostName();
注意:当获得本地主机的域名和主机名时,如果本地主机没有域名,则显示的域名和主机名重名;如果本地主机有域名,就会显示对应的域名。
以下摘录自Jdk 1.8谷歌翻译
public String getCanonicalHostName()
获取此IP地址的完全限定域名。
最好的方法,意味着我们可能无法返回FQDN取决于底层的
系统配置。
如果有安全管理员,则该方法首先使用主机名称调用其checkConnect方法,并-1作为参数,以查看主叫代码是否被允许知道该IP地址的主机名,即连接到主机。
如果不允许操作,它将返回IP地址的文本表示。 结果 :该IP地址的完全限定域名,或者安全检查不允许操作时,该IP地址的文本表示。
从以下版本开始: 1.4
public String getHostName() 获取此IP地址的主机名。
如果此InetAddress是使用主机名创建的,则该主机名将被记住并返回;
否则,将执行反向名称查找,并将基于系统配置的名称查找服务返回结果。
如果有一个安全管理器,它的checkConnect方法首先被调用与主机名和-1作为参数,看看是否允许操作。
如果不允许操作,它将返回IP地址的文本表示。 结果 :该IP地址的主机名,或者安全检查不允许操作时,IP地址的文本表示。
实例299:通过域名获得IP地址
通过InetAddress类的getByName()方法,获得网络中指定域名的InetAddress对象调用该对象的getHostAddress()方法,获得具有该域名的主机IP地址
主要代码如下:
//获得输入的域名 String domain=tf_domain.getText(); //创建InetAddress对象 InetAddress inetAddr=InetAddress.getByName(domain); //获得IP地址 String ip=inetAddr.getHostAddress();
以下摘录自Jdk 1.8谷歌翻译
public static InetAddress getByName(String host) throws UnknownHostException
主机名称可以是机器名称,例如“ java.sun.com ”或其IP地址的文本表示。 如果提供了文字IP地址,则只会检查地址格式的有效性。
为host在字面的IPv6地址指定的,无论是在RFC 2732或RFC中定义的2373字面IPv6地址格式中定义的形式被接受。
还支持IPv6作用域地址。 见here对IPv6的范围地址的描述。
如果主机是null则返回一个InetAddress回送接口地址的InetAddress。
参数:host - 指定的主机,或 null 。
结果:给定主机名的IP地址。
异常:UnknownHostException -
如果没有找到 host IP地址,或者是否为全局IPv6地址指定了scope_id。
SecurityException -
如果安全管理器存在,并且其checkConnect方法不允许该操作
实例300:通过IP地址获得域名和主机名
将IP地址转换成字节数组通过InetAddress类的getByAddress()方法,获得主机中具有指定IP地址的InetAddress对象
调用该对象的getCanonicalHostName()方法,获得对应的域名
通过getHostName()方法,获得对应的主机名。
主要代码如下:
//将IP地址转换为字节数组
String ip=tf_ip.getText();//输入IP地址字符串
String[] ipStr=ip.split("[.]");//转换成字符数组
byte[] ipBytes=new byte[4];
for(int i=0;i<4;i++){
int m=Integer.parseInt(ipStr[i])//转换成整数
byte b=(byte)(m&0xff);//转换为字节
ipBytes[i]=b;//赋值给字节数组
}
//创建本地主机的InetAddress对象 InetAddress inetAddr=InetAddress.getLocalHost(); //获取本地主机的域名 String canonical=inetAddr.getCanonicalHostName(); //获取本地主机的主机名 String host=inetAddr.getHostName();
实例301 获得内网的所有IP地址
获得本机IP地址所属的网段ping网络中的IP地址
通过输入流对象读取所ping结果,并判断是否为内网的IP地址
主要代码如下:
//获取本机IP地址所属的网段 //获得本机的InetAddress对象 InetAddress host=InetAddress.getLocalHost(); //获得本机的IP地址 String hostAddress=host.getHostAddress(); //获得IP地址中最后一个点的位置 int pos=hostAddress.lastIndexOf("."); //对本机的IP地址进行截取,获得网段 String wd=hostAddress.substring(0,pos+1); //对局域网的IP地址进行遍历 for(int i=1;i<=255;i++){ String ip=wd+i; PingIpThread thread=new PingIpThread(ip); thread.start(); } //获得集合中键的Set视图 Set<String> set=pingMap.keySet(); Iterator<String> it=set.itrator();//获得迭代器对象 while(it.hasNext()){ String key=it.next(); String value=pingMap.get(key); if(value.equals("true")){ ta_allIp.append(key+"\n"); } }
//ping网络中的IP地址,通过输入流对象读取所Ping结果,并判断是否为内网的IP地址 //获得所ping的IP进程,-w 280 是等待每次回复的超时时间,-n 1 是要发送的回显请求数 Process process=Runtime.getRuntime().exec("ping"+ip+"-w 280 -n 1"); InputStream is=process.getInputStream();//获得进程的输入流对象 InputStream is=process.getInputStreamReader(is);//创建InputStreamReader对象 BufferReader in=new BufferedReader(isr);//创建缓冲字符流对象 String line=in.readLine();//读取信息 while(line!=null){ if(line!=null&&!line.equals("")){ if(line.substring(0,2).equals("来自") ||(line.length()>10&&line.substring(0,10) .equals("Reply from"))){//判断是ping通过的IP地址 pingMap.put(ip,"true");//向集合中添加IP地址 } } line=in.readLine();//再读取信息 }
10.2网络资源管理
实例302:获取网络资源的大小
-通过URLContentLength()方法获得网络资源大小-在文本框中显示
//获得网络资源大小 public long netSourcesSize(String sUrl) throws Exception{ URL url=new URL(sUrl);//创建URL对象 URLConnection urlConn=url.openConnection();//获得网络连接对象 urlConn.connect();//dakai url引用资源的通信链接 return urlConn.getContentLength();//以字节为单位返回资源的大小 } //在文本框中显示 String address=textFile.getText().trim();//获得输入的网址 long len=netSourceSize(address);//调用方法获取网络资源的大小 textFile_1.setText(String.valueOf(len)+"字节");//在文本框中显示网络资源的大小
实例303:解析网页中的内容
-通过URLConnection类的getInputStream()方法获得网页资源的输入流对象-从该输入流中读取信息
//解析网页内容 public Collection<String> getURLCollection(String urlString){ URL url=null;//声明URL URLConnection<String> urlCollection=new ArrayList<String>();//创建集合对象 try{ url=new URl(urlString);//创建URL对象 conn=url.openConnection();//获得连接对象 conn.connect();//打开到url引用资源的通信连接 InputStream is=conn.getInputStrean();//获取流对象 InputStreamReader in=new INputStreanReader(is,"UTF-8");//转换为字符流 BufferedReader br=new BufferedReader(in);//创建缓冲流对象 String nextLine=br.readLine();//读取信息,解析网页 while(nextLine!=null){ urlCollection.add(nextLine);//解析网页的全部内容,添加到集合中 nextLine=br.readLine();//读取信息,解析网页 } }catch(Exception ex){ ex.printStackTrance(); } return urlCollection; } //输出信息 String address=tf_address.getText().trim();//获得输入的网址 Collection urlCollection=getURLCollection(address);//调用方法,获得网页内容的集合对象 Iterator it=urlCollection.iterator();//获得集合的迭代器对象 while(it.hasNext()){ ta_contet.append((String)it.next()+"\n");//在文本域中显示解析的内容 }
实例304:网络资源的单线程下载
-利用URLConnection对象的getInputStream()方法,获得网络资源的输入流对象-使用FileOutputStream类创建输出流对象,然后使用该类的write()方法,将从输入流获得的网络资源保存到磁盘上,实现网络资源的单线程下载。
//定义download()方法,用于根据参数urlAddr指定的地址,完成网络资源的单线程下载 public void download(String urlAddr){//从指定网址下载文件 try{ URL url=new URL(urlAddr);//创建URL对象 URLConnection urlConn=url.openConnection();//获得连接对象 urlConn.connect();//打开到url引用资源的通信链接 InputStream in=urlConn.getInputStream();//获得输入流对象 int pos=filePath.lastIndexOf("/");//获得路径中最后一个斜杠的位置 String fileName=filePath.substring(pos+1);//截取文件名 FileOutputStream out=new FileOutStream("C:/"+fileName);//创建输出流对象 byte[] bytes=new byte[1024];//声明存放下载内容的字节数组 int len=in.read(bytes);//从输入流中读取内容 while(len!=-1){ out.write(bytes,0,len);//将读取的内容写到输出流 len=in.read(bytes);//继续从输入流中读取内容 } out.close();//关闭输出流 in.close();//关闭输入流 JOptionPane.showMessageDialog(null,"下载完毕"); }catch(Exception e){ e.printStackTrance(); } }
注意:在下载网络资源时,需要及时关闭IO流,因为每个IO流都会占用较多的系统资源,并且IO流并不能被垃圾回收机制回收,当下载网络资源的用户较多时,就会造成不必要的资源浪费,甚至会使系统崩溃。
实例305:网络资源的多线程下载
-创建线程类-使用RandomAccessFile类的seek()方法定位下一个写入点
-通过write()方法写入文件
//实现通过线程类DownMultiThread下载网络资源 public void download(String url, String dest, int threadNum) throws Exception { URL downURL = new URL(url);// 创建网络资源的URL HttpURLConnection conn = (HttpURLConnection) downURL.openConnection();// 打开网络边接 long fileLength = -1;// 用于存储文件长度的变量 int stateFlagCode = conn.getResponseCode();// 获得连接状态标记代码 if (stateFlagCode == 200) {// 网络连接正常 fileLength = conn.getContentLength();// 获得文件的长度 conn.disconnect();// 取消网络连接 } if (fileLength > 0) { long byteCounts = fileLength / threadNum + 1;// 计算每个线程的字节数 File file = new File(dest);// 创建目标文件的File对象 int i = 0; while (i < threadNum) { long startPosition = byteCounts * i;// 定义开始位置 long endPosition = byteCounts * (i + 1);// 定义结束位置 if (i == threadNum - 1) { DownMultiThread fileThread = new DownMultiThread(url, file, startPosition, 0);// 创建DownMultiThread线程的实例 new Thread(fileThread).start();// 启动线程对象 } else { DownMultiThread fileThread = new DownMultiThread(url, file, startPosition, endPosition);// 创建DownMultiThread线程的实例 new Thread(fileThread).start();// 启动线程对象 } i++; } JOptionPane.showMessageDialog(null, "完成网络资源的下载。"); } } //创建一个实现Runnable接口的线程类DownMultiThread,用于实现网络资源的下载 public class DownMultiThread implements Runnable{ private String sUrl = "";// 网络资源地址 private File desFile;// 需要写入的目标文件对象 private long startPos;// 写入的开始位置 private long endPos;// 写入的结束位置 public DownMultiThread(String sUrl,File desFile,long startPos,long endPos) { this.sUrl = sUrl; this.desFile = desFile; this.startPos = startPos; this.endPos = endPos; } @Override public void run() { try { URL url = new URL(sUrl);// 创建下载资源的URL对象 HttpURLConnection conn = (HttpURLConnection)url.openConnection();// 打开连接对象 conn.setRequestProperty("User-Agent", "NetFox");// 设置请求属性 String rangeProperty = "bytes="+startPos+"-";// 定义范围属性 if (endPos > 0){ rangeProperty = "bytes="+startPos+"-" + endPos;// 调整范围属性的值 } conn.setRequestProperty("RANGE", rangeProperty);// 指定范围属性 RandomAccessFile out = new RandomAccessFile(desFile, "rw");// 创建可读写的流对象 out.seek(startPos);// 指定读写的开始标记 InputStream in = conn.getInputStream();// 获得网络资源的输入流对象 BufferedInputStream bin = new BufferedInputStream(in);// 创建输入缓冲流对象 byte[] buff = new byte[2048];// 创建字节数组 int len = -1;// 声明存放读取字节数的变量 len=bin.read(buff);// 读取到内容并添加到字节数组 while (len!=-1){ out.write(buff,0,len);// 写入磁盘文件 len=bin.read(buff);// 读取到内容并添加到字节数组 } out.close();// 关闭流 bin.close();// 关闭流 conn.disconnect();// 断开连接 }catch(Exception ex) { JOptionPane.showMessageDialog(null, ex.getMessage()); } } }
实例306下载网络资源的断点续传
本实例主要是通过设置请求参数RANGE实现的,通过该参数,可以指定下载网络资源的字节区间,从而实现每次下载部分网络资源的功能。全部代码如下:
import java.awt.BorderLayout; import java.awt.Color; import java.awt.EventQueue; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JTextField; @SuppressWarnings("serial") public class BreakPointSuperveneFrame extends JFrame { private JTextField tf_totalLength; private JTextField tf_residuaryLength; private JTextField tf_readToPos; private JTextField tf_address; private JTextField tf_endPos; private JTextField tf_startPos; private String urlAddress = "";// 用于存储网络资源的地址 private long totalLength = 0;// 存储网络资源的大小,以字节为单位 private long readToPos = 0;// 存储上次读取到的位置 private long residuaryLength = 0;// 存储未读内容的大小 /** * Launch the application * * @param args */ public static void main(String args[]) { EventQueue.invokeLater(new Runnable() { public void run() { try { BreakPointSuperveneFrame frame = new BreakPointSuperveneFrame(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame */ public BreakPointSuperveneFrame() { super(); getContentPane().setLayout(null); setTitle("下载网络资源的断点续传"); setBounds(100, 100, 514, 238); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); tf_startPos = new JTextField(); tf_startPos.setBounds(80, 165, 113, 22); getContentPane().add(tf_startPos); final JLabel label = new JLabel(); label.setText("起始位置:"); label.setBounds(10, 167, 74, 18); getContentPane().add(label); final JLabel label_1 = new JLabel(); label_1.setText("结束位置:"); label_1.setBounds(199, 167, 74, 18); getContentPane().add(label_1); tf_endPos = new JTextField(); tf_endPos.setBounds(267, 165, 117, 22); getContentPane().add(tf_endPos); final JLabel label_2 = new JLabel(); label_2.setText("网络资源的地址:"); label_2.setBounds(10, 52, 113, 18); getContentPane().add(label_2); tf_address = new JTextField(); tf_address.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { try { urlAddress = tf_address.getText().trim(); URL url = new URL(urlAddress);// 获得网络资源的URL HttpURLConnection connection = (HttpURLConnection) url .openConnection();// 获得连接对象 connection.connect();// 连接网络资源 totalLength = connection.getContentLength();// 获得网络资源的长度 connection.disconnect();// 断开连接 tf_totalLength.setText(String.valueOf(totalLength));// 显示总长度 tf_readToPos.setText("0");// 显示上次读取到的位置 residuaryLength = totalLength;// 未读内容为文件总长度 tf_residuaryLength.setText(String.valueOf(residuaryLength));// 显示未读内容 } catch (MalformedURLException e1) { e1.printStackTrace(); } catch (IOException e2) { e2.printStackTrace(); } } }); tf_address.setBounds(119, 50, 365, 22); getContentPane().add(tf_address); final JLabel label_3 = new JLabel(); label_3.setForeground(new Color(0, 0, 255)); label_3.setFont(new Font("", Font.BOLD, 14)); label_3.setText("输入网络资源的地址并回车,可以获得网络资源的大小。"); label_3.setBounds(10, 10, 384, 22); getContentPane().add(label_3); final JLabel label_4 = new JLabel(); label_4.setForeground(new Color(128, 0, 0)); label_4.setText("网络资源的大小为"); label_4.setBounds(10, 76, 113, 38); getContentPane().add(label_4); final JLabel label_5 = new JLabel(); label_5.setText("上次读取到"); label_5.setBounds(10, 123, 74, 18); getContentPane().add(label_5); tf_readToPos = new JTextField(); tf_readToPos.setBounds(80, 121, 113, 22); tf_readToPos.setEnabled(false); getContentPane().add(tf_readToPos); final JLabel label_6 = new JLabel(); label_6.setText("字节处,还剩"); label_6.setBounds(202, 123, 87, 18); getContentPane().add(label_6); tf_residuaryLength = new JTextField(); tf_residuaryLength.setBounds(285, 120, 117, 22); tf_residuaryLength.setEnabled(false); getContentPane().add(tf_residuaryLength); final JLabel label_7 = new JLabel(); label_7.setText("字节未读。"); label_7.setBounds(404, 123, 80, 18); getContentPane().add(label_7); final JLabel label_4_1 = new JLabel(); label_4_1.setForeground(new Color(128, 0, 0)); label_4_1.setText("个字节。"); label_4_1.setBounds(404, 76, 80, 38); getContentPane().add(label_4_1); tf_totalLength = new JTextField(); tf_totalLength.setBounds(119, 84, 283, 22); tf_totalLength.setEnabled(false); getContentPane().add(tf_totalLength); final JButton button = new JButton(); button.setBounds(395, 162, 89, 28); getContentPane().add(button); button.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { if (totalLength == 0) { JOptionPane.showMessageDialog(null, "没有网络资源。\n\n请输入正确的网址,然后回车。"); return; } long startPos = 0;// 起始位置 long endPos = 0;// 结束位置 try { startPos = Long.parseLong(tf_startPos.getText().trim());// 起始位置 endPos = Long.parseLong(tf_endPos.getText().trim());// 结束位置 } catch (Exception ex) { JOptionPane.showMessageDialog(null, "输入的起始位置或结束位置不正确。"); return; } readToPos = endPos;// 记录读取到的位置 residuaryLength = totalLength - readToPos;// 记录未读内容的大小 tf_readToPos.setText(String.valueOf(readToPos));// 显示读取到的位置 tf_residuaryLength.setText(String.valueOf(residuaryLength));// 显示未读字节数 tf_startPos.setText(String.valueOf(readToPos));// 设置下一个读取点的开始位置 tf_endPos.setText(String.valueOf(totalLength));// 设置下一个读取点的结束位置 tf_endPos.requestFocus();// 使结束位置文本框获得焦点 tf_endPos.selectAll();// 选择结束位置文本框中的全部内容,方便输入结束位置值 download(startPos, endPos);// 调用方法进行下载 } }); button.setText("开始下载"); } public void download(long startPosition, long endPosition) { try { URL url = new URL(urlAddress);// 获得网络资源的URL HttpURLConnection connection = (HttpURLConnection) url .openConnection();// 获得连接对象 connection.setRequestProperty("User-Agent", "NetFox");// 设置请求属性 String rangeProperty = "bytes=" + startPosition + "-";// 定义请求范围属性 if (endPosition > 0) { rangeProperty += endPosition;// 调整请求范围属性 } connection.setRequestProperty("RANGE", rangeProperty);// 设置请求范围属性 connection.connect();// 连接网络资源 InputStream in = connection.getInputStream();// 获得输入流对象 String file = url.getFile();// 获得文件对象 String name = file.substring(file.lastIndexOf('/') + 1);// 获得文件名 FileOutputStream out = new FileOutputStream("c:/" + name, true);// 创建输出流对象,保存下载的资源 byte[] buff = new byte[2048];// 创建字节数组 int len = 0;// 定义存储读取内容长度的变量 len = in.read(buff);// 读取内容 while (len != -1) { out.write(buff, 0, len);// 写入磁盘 len = in.read(buff);// 读取内容 } out.close();// 关闭流 in.close();// 关闭流 connection.disconnect();// 断开连接 if (readToPos > 0 && readToPos == totalLength) { JOptionPane.showMessageDialog(null, "完成网络资源的下载。\n单击“确定”按钮退出程序。"); System.exit(0); } } catch (Exception e) { e.printStackTrace(); } } }
参考书籍《Java开发实战1200例》(第二卷)
相关文章推荐
- 《Spring 3.x 企业应用开发实战》学习笔记 第三章 IoC容器概述 3.2 相关Java基础知识 类装载器 反射机制
- Java WEB开发实战 之 第二部分:Web应用基础知识【私塾在线原创】
- 《Spring 3.x 企业应用开发实战》学习笔记 第三章 IoC容器概述 3.2 相关Java基础知识 类装载器 反射机制
- Java在Client/Server网络中的应用-Java基础-Java-编程开发
- Java 在Client/Server 网络中的应用-Java基础-Java-编程开发
- Java应用技巧-Java基础-Java-编程开发
- Java.util包简介并教您如何开发应用之二-Java基础-Java-编程开发
- 应用Java技术开发WAP应用程序-Java基础-Java-编程开发
- Java Servlet 编程及应用之二-Java基础-Java-编程开发
- 网络-两远程客户端之间的通讯原理-Java基础-Java-编程开发
- [零基础学JAVA]Java SE实战开发-37.MIS信息管理系统实战开发[文件保存](1) 推荐
- Java Servlet 编程及应用之三-Java基础-Java-编程开发
- [零基础学JAVA]Java SE实战开发-37.MIS信息管理系统实战开发[文件保存](2) 推荐
- java基础教程-网络应用
- 网络开发应用JAVA EJB开发中间件(weblogic oracle ejb)
- Java Servlet 编程及应用(一)-Java基础-Java-编程开发
- Java规则引擎工作原理及其应用-Java基础-Java-编程开发
- 企业级应用中的Applet和Servlet的通信-Java基础-Java-编程开发
- 实战体会Java的多线程编程-Java基础-Java-编程开发
- 学习使用J2EE Web应用的事件功能-Java基础-Java-编程开发