java基础--网络编程之 自定义浏览器和URL类的使用
笔记摘要:
本篇文章主要介绍了浏览器的工作原理,然后通过自定义的浏览器发送请求来模拟,并介绍了URL类,该类将Socket对象封装,使用起来
更为方便,同时将使用URL对象的自定义浏览器和图形化界面相结合,实现了一个简易的图形化浏览器功能。
最后对于浏览器访问网址时的域名解析进行了解释。
一、自定义浏览器
现实中的浏览器在输入网址后,通常是发送一系列的请求消息,以便服务端识别,服务器在处理客户端的请求之后返回资源文件。
示例说明:
这里主要模拟真实浏览器发送请求,并获取返回的数据,但是并不能对服务端反馈的信息进行解析格式上的解析,因为Socket是在传输层,
可以使用下面的URL封装的对象实现信息的拆包,URL的使用在应用层
自定义浏览器代码:
import java.io.*; import java.net.*; class MyIE { public static void main(String[] args)throws Exception { Socket s = new Socket("192.168.1.254",8080); PrintWriter out = new PrintWriter(s.getOutputStream(),true); //向服务端发送请求消息 out.println("GET /myweb/demo.html HTTP/1.1"); out.println("Accept: */*"); out.println("Accept-Language: zh-cn"); out.println("Host: 192.168.1.254:11000"); out.println("Connection: closed"); BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream())); String line = null; //读取反馈消息 while((line=bufr.readLine())!=null){ System.out.println(line); } s.close(); } }
二、URL类
URL类
代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,
例如对数据库或搜索引擎的查询。
URL对象的方法示例代码
import java.net.*; class URLDemo { public static void main(String[] args) throws MalformedURLException{ //根据 String 表示形式创建 URL 对象 URL url = new URL("http://192.168.1.254/myweb/demo.html?name=haha&age=30"); System.out.println("getProtocol() :"+url.getProtocol()); //获取此 URL 的协议名称 System.out.println("getHost() :"+url.getHost()); //获取此 URL 的主机名(如果适用) System.out.println("getPort() :"+url.getPort()); //获取此 URL 的端口号。 System.out.println("getPath() :"+url.getPath()); //获取此 URL 的路径部分。 System.out.println("getFile() :"+url.getFile()); //获取此 URL 的文件名。 System.out.println("getQuery() :"+url.getQuery()); //获取此 URL 的查询部 /* 当访问时没有指定端口,就默认访问80端口的原因: 当没有指定端口号时 getPort()==-1 int port = getPort(); if(port==-1) port = 80; getPort()==-1 */ } }
三、使用URL进行网络连接
package cn.xushuai.test; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; public class URLTest { public static void main(String[] args) throws Exception{ //根据 String 表示形式创建 URL 对象 URL url = new URL("http://192.168.1.254:8080/myweb/demo.html"); // 获取一个 URLConnection 对象,它表示到 URL 所引用的远程对象的连接 //内部封装了socket,所以直接就可以连接,这里是在应用层 URLConnection conn = url.openConnection(); //System.out.println(conn); //读取服务端反馈的信息 InputStream in = conn.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); System.out.println(new String(buf,0,len)); } }
四、自定义图形界面浏览器
这里我们需要建立一个Web应用。在C:\apache-tomcat-6.0.35\webapps 下建立一个文件夹myweb并新建一个html文件
作为资源文件
<html> <body> <h1>我的主页</h1> <font size=5 color = red>欢迎你的到来!</font> <div> 春天花会开,鸟儿自由自在!</br> 春天花会开,鸟儿自由自在!</br> 春天花会开,鸟儿自由自在!</br> 春天花会开,鸟儿自由自在!</br> 春天花会开,鸟儿自由自在!</br> </div> </body> </html>
简易的图形化界面浏览器效果图
import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; class MyIEByGUI2{ private Frame f; private TextField tf; private Button but; private TextArea ta; private Dialog d; private Label lab; private Button okBut; //创建图形化界面 MyIEByGUI2(){ init(); } public void init(){ f = new Frame("my window"); f.setBounds(300,100,600,500); f.setLayout(new FlowLayout()); tf = new TextField(60); but = new Button("转到"); ta = new TextArea(25,70); d = new Dialog(f,"提示信息-self",true); d.setBounds(400,200,240,150); d.setLayout(new FlowLayout()); lab = new Label(); okBut = new Button("确定"); d.add(lab); d.add(okBut); f.add(tf); f.add(but); f.add(ta); myEvent(); f.setVisible(true); } //事件监听器 private void myEvent(){ okBut.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ d.setVisible(false); } }); d.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ d.setVisible(false); } }); tf.addKeyListener(new KeyAdapter(){ public void keyPressed(KeyEvent e){ try{ if(e.getKeyCode()==KeyEvent.VK_ENTER) showDir(); } catch (Exception ex){ } } }); but.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ try{ showDir(); } catch (Exception ex){ } } }); f.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0); } }); } //显示网页内容 private void showDir()throws Exception{ ta.setText(""); String urlPath = tf.getText();//http://192.168.1.254:8080/myweb/demo.html URL url = new URL(urlPath); //获取一个网络连接对象 URLConnection conn = url.openConnection(); //读取服务端反馈的信息 InputStream in = conn.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); ta.setText(new String(buf,0,len)); } public static void main(String[] args) { new MyIEByGUI2(); } }
五、小知识点:
1、当使用Socket
()
空构造函数
时,我们要通过connect
(SocketAddress endpoint)
来连接。
SocketAddress为抽象类,其子类为InetSocketAddress
子类的构造函数:
InetSocketAddress(InetAddress addr,int port),它与InetAddress的区别是多封装了一个端口号
2.ServerSocket(int port ,int backlog)
backlog:闯入连接指示(对连接的请求)的最大队列长度被设置为backlog参数,即最大连接数
六、域名解析
客户机使用浏览器访问主机名:www.sina.com.cn时都做了什么?
首先需要将主机名翻译成IP地址,才能访问,这就是我们需要域名解析
解析过程:
1、 先找本地的hosts文件中的映射关系,本地有,走本地。
本地没有,到公网去找DNS服务器(该服务器记录的是主机名和IP地址的映射关系)
2、 将主机名翻译成IP地址,获取IP地址之后再次向该IP地址发送请求,即向sina主机(服务器)发送请求。
3、有的话就走本地,没有走公网上的地址,