笔记摘要:
本篇文章主要介绍了浏览器的工作原理,然后通过自定义的浏览器发送请求来模拟,并介绍了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、有的话就走本地,没有走公网上的地址,