别样JAVA学习(十四)网络编程1.2

7、自定义图形界面浏览器-Tomcat服务端

那么大家接下来,刚才咱们做了个DOS命令行,咱是不是可以做个图形化界面。

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;

class MyIEByGUI{
	//1,定义窗体组件
	private Frame f;
	private TextField tf;
	private Button b;
	private TextArea ta;
	
	private Dialog d;
	private Label dl;
	private Button db;
	
	MyIEByGUI(){
		init();
	}
	public void init(){
		//2,设置窗体组件
		f=new Frame("my window");
		f.setBounds(300,100,700,500);
		f.setLayout(new FlowLayout());
			//文本框,按钮,文本域
		tf=new TextField(60);
		f.add(tf);
		b=new Button("转到");
		f.add(b);
		ta=new TextArea(25,70);
		f.add(ta);
		//3,添加事件
		myEvent();
		//4,显示窗体
		f.setVisible(true);
	}
	//窗体事件
	public void myEvent(){
		f.addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent e){
				System.exit(0);
			}
		});
		//点击转到按钮显示文本
		b.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				try{
					showDir();
				}catch(Exception ex){
					throw new RuntimeException("上传失败");
				}
			}
		});
		//敲Enter键显示文本
		tf.addKeyListener(new KeyAdapter(){
			public void keyPressed(KeyEvent e){
				if(e.getKeyCode()==KeyEvent.VK_ENTER)
					try{
						showDir();
					}catch(Exception ex){
						throw new RuntimeException("上传失败");
					}
			}
		});
	}
	private void showDir()throws IOException{
		ta.setText("");
		String url=tf.getText();
		int index1=url.indexOf("//")+2;
		int index2=url.indexOf("/",index1);
		
		String str=url.substring(index1,index2);
		String[] arr=str.split(":");
		String host=arr[0];
		int port=Integer.parseInt(arr[1]);
		String path=url.substring(index2);
		ta.setText(host+"..."+port+"..."+path);
		//1,定义码头
		Socket s=new Socket(host,port);
		//2,定义输出流
		PrintWriter out=new PrintWriter(s.getOutputStream(),true);
		out.println("GET "+path+" HTTP/1.1");
		out.println("Accept: */*");
		out.println("Accept-Language: zh-CN");
		out.println("User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)");
		out.println("Host: 10.2.172.93:11001");
		out.println("Connection: Keep-Alive");
		
		out.println();
		out.println();
		//3,定义接收服务端流
		InputStream in=s.getInputStream();
		byte[] buf=new byte[1024];
		int len=0;
		while((len=in.read(buf))!=0){
			String line=new String(buf,0,len);
			ta.append(line+"\r\n");
		}
		s.close();
	}
	public static void main(String[] args){
		new MyIEByGUI();
	}
	public static void sop(Object obj){
		System.out.println(obj);
	}
}
完事了,就差数据解析了,但是数据我们一样获取到。

等下一节,咱再封装一下,咱写百度新浪一回车,百度新浪数据都拿到,就是解析不了。

浏览器强大就强大在它里面挂了N多解析引擎。html解析、css解析、javascript解析,N多内置引擎很吊。

至于socket,它能做,咱也能做。但有个问题浏览器的数据咱是不是多了一部分。

浏览器的是应用层的部分,但很遗憾咱走的是传输层,咱把传输层的数据全都拿过来了,

而咱浏览器把HTTP协议封装的信息是不是给拆掉了,数据的向上传输到应用层的时候是不是要拆包,对吧,浏览器把那个包给拆了。

咱没拆,下一节就把它拆了。跟浏览器一模一样。咱是不是刚才解析url要死,这事负责吧,那java是不是会提供个对象给我们解决啊。

待会下一节,咱就学一个对象,把这件事给解决了,要多easy就有多easy。你不写对象是最es


8、URL-URLConnection

这上一节,咱做了个小程序,咱输入个url可以去访问这个服务端是吧。

那么服务端tomcat服务器给我们发回来了一些信息。

这些信息当中啊,除了信息的主体之外,是不是响应头信息和数据体之间有空行。

那么这个信息大家注意到,为什么浏览器访问完以后就没有这个信息呢。


这就是小问题了,首先我们分析一点就是,原来咱用的是传输层的协议啊,

我们就获取到了服务层给我们发过来所有数据,并把数据都展示在了文本区域当中。

而浏览器做的事情将这些消息做了个解析,把应用层协议消息的部分解析完拆包扔掉了,

把正文数据主体部分显示在了自己接收的区域范围内。


那么大家看,上一章咱写的代码稍微有点麻烦,麻烦在哪?

就是我们对url数据其实是进行了获取其中的每一部分,获取完了,

采取封装对象,向服务器短发送我们的请求资源。很麻烦。


那么思考另外一问题,像这样的url路径是不是很常见,而且它里面包含东西非常多。

所以相对复杂的东西我们是不是要去找有没有相对应的对象,如果有这个对象就拿来用。

如果没有,我们也有将上一节的代码中的url封装成一个对象,以便下次来用。


应用层有个HTTP协议,把HTTP头部分数据去掉了,把数据主体返回来了。

import java.net.*;

class URLDemo{
	public static void main(String[] args)throws MalformedURLException{
		URL url=new URL("http://10.2.172.93:8080/myweb/demo.html?name=hh&age=30");
		
		sop("getProtocol:"+url.getProtocol());
		sop("getHost:"+url.getHost());
		sop("getPort:"+url.getPort());
		sop("getPath:"+url.getPath());
		sop("getFile:"+url.getFile());
		sop("getQuery:"+url.getQuery());
	}
	public static void sop(Object obj){
		System.out.println(obj);
	}
}

import java.net.*;
import java.io.*;

class URLConnectionDemo{
	public static void main(String[] args)throws Exception{
		URL url=new URL("http://10.2.172.93:8080/myweb/demo.html");
		
		URLConnection conn=url.openConnection();
		sop(conn);
		InputStream in=conn.getInputStream();
		byte[]buf=new byte[1024];
		int len=in.read(buf);
		sop(new String(buf,0,len));
	}
	public static void sop(Object obj){
		System.out.println(obj);
	}
}

将上一节中的showDir方法内部修改:
	private void showDir()throws IOException{
		ta.setText("");
		String url1=tf.getText();
		URL url=new URL(url1);
		
		URLConnection conn=url.openConnection();
		sop(conn);
		InputStream in=conn.getInputStream();
		byte[]buf=new byte[1024];
		int len=in.read(buf);
		ta.setText(new String(buf,0,len));
	}

做完了,但很遗憾不能对接收到服务端的数据进行解析。


9、小知识点

简单介绍点小东西,大家会发现我们在学socket时,它是不是有一个向主机发送空参数的一个构造函数。

SocketAddress与InetAddress的区别,看SocketAddress的子类InetSocketAddress吧。InetAddress封装的是IP地址,InetSocketAddress封装的是(IP地址+端口号)。

backlog是限制人数参数。


10、域名解析

接下来,我们讲一点网络知识,比较重点的一部分。

我在进行浏览器写入一个网址访问某一台主机的时候,它到底做了什么事情。

http://10.2.172.93:8080/myweb/demo.html浏览器在进行这句话解析以后是不是要先看协议啊。

看完这个协议后,会去启动相对应的协议并解析后面的主机和后面的端口。

http://www.sina.com.cn

想要主机名翻译成IP地址,需要域名解析,需要DNS域名解析服务器。

解析sina主机名对应的IP地址,主机名和IP地址映射的关系。


假如你是电信的宽带,你去访问联通的DNS,可不可以?当然可以。你访问美国的DNS都没问题。

但,有可能你去请求美国时,访问时间过长,过时了,那就失败了。

还有你去访问美国的DNS服务器(在我们的本地连接里的IP4属性修改里),可能没有你想要的网址。


还有如果走http://127.0.0.1:8080(http://localhost:8080)为什么这两个是对应的。

其实127和localhost映射关系就在本机上C:\windows\system32\drivers\etc\hosts


其实不难发现访问www.sina.com会先找本机hosts,这主机名有没有对应的地址,如有就会反馈到浏览器。

这有什么用?例如:某个软件启动时去访问你是否注册了软件,是否是正版的,

那么你可以可以在这里添加该软件登录到的网址指向127.0.0.1,不让该软件更新。

还可以屏蔽掉某些恶意网址。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值