java 自学日志 【十六】---网络编程

来源:互联网 发布:高中算法初步程序语言 编辑:程序博客网 时间:2024/05/16 19:48
------android培训,java培训,期待与您交流------
网络编程:
网络编程是为了实现不同主机间的数据通信,要实现通讯,则要首先知道对方的IP和端口号,同时还要明确双方使用的通信规则(传输协议)。

IP地址,端口号和传输协议就是网络通讯的三要素:
①IP地址:是主机在网络上的地址,在网上的唯一标识,127.0.0.1是本地回环地址,可测试网卡是否损坏;
②端口号:数据要发送到对方指定的应用程序上,为了标识这些应用程序,用数字对其标识,这些数字就是端   口,或被称为逻辑端口;它并无物理实体与之对应;有效端口号从0~65535,其中0~1024是系统保留的                    端口号;
一些常见的端口:浏览器:80 ;     tomcat服务器:8080;  mysql:3306;
③传输协议:要完成传输,还要遵守相同的通信协议,国际通用协议是 TCP/IP协议,既能用于局域网,也可以                 用于广域网,除了TCP/IP,还有 UDP,FTP,HTTP等协议;

网络模型:主要有两个网络模型,一是OSI模型,一是TCP/IP模型;
OSI模型:从顶到底层 分别是: 应用层,表示层,会话层,传输层,网络层,数据链路层,物理层,分七层;
TCP/IP模型:为了简化,TCP/IP将OSI的应用层,表示层,会话层合并为应用层,数据链路层和物理层合并成      主机至网络层,所以它由 应用层,传输层,网际层,主机至网络层组成;
FTP,HTTP都在应用层,TCP,UDP在传输层,IP在网际层;
数据封包:数据从应用层开始,每经一层,都加入该层的标识信息,直到物理层,这个过程叫数据封包,之后           变成二进制数据从物理设备上输出;
数据拆包:去掉每层的标识信息,获取数据的过程就是拆包过程;

网络编程现阶段主要是在网际层,传输层,而javaweb开发主要是在应用层;
java中对各个层都创建了对象与之对应,以方便我们开发使用;

IP地址:是数字,由四段组成,如192.168.1.1,使用时不便于记忆,所以有与之对应的主机名,主机名与IP地址相对应;IP常用的方法如下:都在java。net包中;
InetAddress: getLocalHost();可获取主机名和本地地址;
getHostAddress():主机地址的字符串表现形式;
getHostName():获取主机名称;
如果网络获取主机名称,可能出现解析不成功的情况,那么IP地址就是主机名,getByName("")可通过给定主机名,获取主机的IP地址;
演示:
import java.net.*;class  IPDemo{public static void main(String[] args) throws Exception{InetAddress i = InetAddress.getLocalHost();System.out.println(i.toString());System.out.println("address:"+i.getHostAddress());System.out.println("name:"+i.getHostName());InetAddress [] ia = InetAddress.getAllByName("www.renren.com");for(InetAddress s : ia){System.out.println(s.toString());}//System.out.println("address:"+ia.getHostAddress());//System.out.println("name:"+ia.getHostName());}}

TCP/IP和UDP协议:两者都在传输层;
两者的区别:
①UDP:(User Datagram Protocol),用户数据报协议,是一种面向无连接的不可靠协议,它将数据源和目的封装成数据报包,在不需要建立连接的情况下就可实现传输,每个数据报包大小限制在64K内,特点是传输速度快;存在数据丢失的可能,主要应用于即时数据的传输,如QQ聊天程序,对话机,网络视频会议等;

②TCP:(Transmission Control Protocol),传输控制协议,它是面向连接的可靠的传输协议,通过三次握手的形式完成数据传输通道的连接,传输大量的数据,特点是速度相对较慢,适合对数据完整性要求高的程序,如下载应用程序;

Socket:(插座,套接字):
网络编程其实就是socket编程,它是为网络服务的一种机制,每个应用程序都有一个socket通信端点,可以把socket想象为每个应用程序的插座,通信的两端都有socket,数据在两个socket之间通过IO传输;

UDP传输:UDP两端是发送端和接受端;
DatagramSocekt:UDP传输专用的程序通信断电,既能发送也能接受;
DatagramPacket: 数据报包,封装了UDP传输的数据报包,里面可以设置发送目的地的IP地址,端口和内容;

广播地址:每个网段尾数为255的IP 地址,如192.168.1.255就是一个广播地址;
UDP代码演示:
/*  需求:通过Udp传输方式,将一段文字数据发送出去。  定义一个udp发送端。  思路:  1。建立UDPsocket服务。  2.提供数据,并将数据封装到数据包中。  3.通过socket服务的发送功能,将数据包发出去。  4.关闭资源。  */  import java.net.*;class UDPSend{public static void main(String[] args) throws Exception{ //1.创建UDP服务,通过DatagramSocket对象。DatagramSocket ds = new DatagramSocket(6666);//2.确定数据,并封装成数据包。DatagramPacket(byte[] buf, int length, InetAddress address, int port)byte[] buf = "传输数据成功".getBytes(); DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.102"),10000);//3.通过socket服务,将已有的数据包发送出去,通过send方法。ds.send(dp);//4.关闭资源。它使用了底层的资源,所以要关闭资源。 ds.close();}}/*  需求;  定义一个应用程序,用于接收并处理数据。    定义udp接受端  思路:  1.定义socket服务,通常会监听一个端口,其实就是给这个接受网络应用程序定义一个数字标示。      方便与明确哪些数据过来该应用程序可以处理。  2.定义一个数据包,因为要存储要接受到的字节数据,  因为数据包对象中有更多功能可以提取字节数据中的不同数据信息。  3.通过socket服务的receive方法将收到的数据存入已定义的数据包中。  4.通过数据包对象的特有功能,将这些不同的数据取出,打印在控制台上。  5.关闭资源。  */  class UDPReceive{public static void main(String[] args) throws Exception{//1.创建udpsocket,建立端点。这里必须定义监听的端口,其实就是给网络应用程序定义数字标识。DatagramSocket ds = new DatagramSocket(10000);//2.定义数据包,用于存储数据。byte[] buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf,buf.length);//3.通过服务的receive方法,将收到的数据存入到数据包中。ds.receive(dp);//4.获取数据包中的方法获取其中的数据String ip = dp.getAddress().getHostAddress();String data= new String(dp.getData(),0,dp.getLength());int port = dp.getPort();System.out.println(ip+"--"+data+"--"+port);ds.close();}}
UDP代码演示2:
import java.net.*;import java.io.*;//键盘录入UDP传输class  UDPSend2{public static void main(String[] args) throws Exception{DatagramSocket ds = new DatagramSocket();BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));String line = null;while((line=bufr.readLine())!=null){if("886".equals(line))break;byte [] b = line.getBytes();//192.168.1.255是这个网段的广播地址,用它就能实现局域网群聊。  DatagramPacket dp = new DatagramPacket(b,b.length,InetAddress.getByName("192.168.1.255"),10001);ds.send(dp);}ds.close();}}class UDPRece2{public static void main(String[] args) throws Exception{DatagramSocket ds = new DatagramSocket(10001);while(true){byte[] buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf,buf.length);ds.receive(dp);String ip =dp.getAddress().getHostAddress();String data = new String(dp.getData(),0,dp.getLength());System.out.println(ip+"说:"+data);}}}

利用UDP,编写一个聊天程序
有接受数据的部分,和发数据的部分。
这两部分需要同时执行。那就需要用到多线程技术。
一个线程控制收,一个线程控制发。
因为收和发动作是不一致的,所以要定义两个run方法,
而且run方法要封装到不同的类中。
import java.net.*;import java.io.*;class Send implements Runnable{private DatagramSocket ds;//public Send(DatagramSocket ds){this.ds = ds;}public void run(){try{BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));String line = null;while((line = bufr.readLine())!=null){if("886".equals(line))break;byte[] buf =line.getBytes();//把发送地址,设为广播地址,InetAddress i = InetAddress.getByName("192.168.1.255");DatagramPacket dp=new DatagramPacket(buf,0,buf.length,i,10020);ds.send(dp);}ds.close();}catch (Exception e){throw new RuntimeException("发送端失败");}}}class Rece implements Runnable{private DatagramSocket ds;public Rece(DatagramSocket ds){this.ds = ds;}public void run(){try{while(true){byte [] buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf,buf.length);ds.receive(dp);String ip = dp.getAddress().getHostAddress();String data = new String(dp.getData(),0,dp.getLength());System.out.println("ip:"+ip+" data:"+data);}}catch (Exception e){throw new RuntimeException("接受端失败");}}}class  ChatDemo{public static void main(String[] args) throws Exception{DatagramSocket sendSoket = new DatagramSocket();DatagramSocket receSoket = new DatagramSocket(10020);new Thread(new Send(sendSoket)).start();new Thread(new Rece(receSoket)).start();}}

TCP传输:对应的是客户端和服务端

Socket:TCP传输客户端通信端点;
ServerSocket: TCP传输服务端端点;serversocket(port,backlog)这个构造函数中的backlog用于指定客户端的最大连接数;

因为TCP需要建立连接,所以socket客户端一建立就要指定服务端的IP和端口,而在服务端建立时,要设置监听的端口,TCP连接成功后,在客户端和服务端就会产生网络流,客户端提供对网络流进行读写的输入流和输出流对象,服务端操作网络流时,先获取客户端的socket对象,然后利用该socket的字节输入输出流进行读写操作,客户端和服务端进行多次交互时,注意阻塞式方法对程序的影响;
TCP代码演示一:
演示TCP传输。  
1.tcp分客户端和服务端。  
2.客户端对应的对象是Socket。  
    服务端对应的对象是SeverSocket  
/*  客户端:  通过查阅Socket对象,发现在该对象建立时,就可以连接指定的主机。  因为TCP是面向连接的,所以在建立Socket服务时,就要有服务端存在,  并连接成功,形成通路后,在该通道进行数据的传输。    需求:给服务段发送一个文本数据。  步骤:  1.创建Socket服务,并指定要连接的主机和端口。  2.为了发送数据,应该获取Socket流中的输出流。 3.获取输出流后写入数据。  4.socket关闭客户端Socket服务,也就关闭了网络流资源。*/ import java.net.*;import java.io.*;class  TCPClient{public static void main(String[] args) throws Exception{Socket s = new Socket("192.168.1.102",10086);OutputStream out = s.getOutputStream();out.write("i am coming!".getBytes());s.close();}}/*  难在服务端上。  需求:定义端点,接受数据,并打印在控制台上。    服务端:  1.建立服务端的Socket服务,通过SeverSocket();并监听一个端口。  2. 获取连接过了的客户端对象。      通过SeverSocket的accept方法。没有就会等,所以这个方法是阻塞式的。  3.客户端如果发过了数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流读取发过了的数据。并打印在控制台上。  4.关闭服务。(可选操作,服务端一般是一直开着的)。  */  class TCPServer{public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10086);Socket s = ss.accept();String ip = s.getInetAddress().getHostAddress();System.out.println(ip+"......connect");InputStream in = s.getInputStream();byte[] buf = new byte[1024];int len = in.read(buf);System.out.println(new String(buf,0,len));s.close();}}

演示代码二:
演示tcp的传输的的客户端和服务端的互访。  
需求:客户端给服务端发送数据,服务端收到数据后,给客户端反馈信息。  
/*  客户端:  1.建立socket服务,指定要连接的主机和端口  1.获取Socket流中的输出流,将数据写入到该流中,通过网络发送给服务端。  3.获取socket流中的输入流,将服务端反馈的数据获取到,并打印,  4.关闭客户端资源。  */  import java.io.*;import java.net.*;class  TCPC2{public static void main(String[] args) throws Exception{Socket s = new Socket("192.168.1.102",10010);OutputStream out = s.getOutputStream();out.write("收到了吗?".getBytes());InputStream in = s.getInputStream();byte[] buf = new byte[1024];int len = in.read(buf);System.out.println(new String(buf,0,len));s.close();}}class  TCPS2{public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10010);Socket s = ss.accept();String ip = s.getInetAddress().getHostAddress();System.out.println(ip+"....connect");InputStream in = s.getInputStream();byte[] buf = new byte[1024];int len = in.read(buf);System.out.println(new String(buf,0,len));OutputStream out = s.getOutputStream();out.write("收到了".getBytes());s.close();}}

演示代码三:
需求:建立一个文本转换服务器。 
客户端给服务端发送文本,服务端会将文本转成大写再返回给客户端。 
而且,客户端可以不断的进行文本转换。当客户端输入over,转换就结束。 
分析: 
客户端: 
既然是操作设备上的数据,那么就可以使用io技术,并按照IO的操作规律来思考。 
源:键盘录入 
目的:网络设备,也就是网络输出流, 
而且操作的是文本数据,可以选择字符流。 
步骤: 
1,建立服务 
2.获取键盘录入 
3,将数据发给服务端。 
4.获取服务端返回的大写数据。 
5.结束,关闭资源。 
都是文本数据,可以使用字符流进行操作。同时提高效率,要加入缓冲。
import java.io.*;import java.net.*;class TCPC3{public static void main(String[] args) throws Exception{Socket s = new Socket("192.168.1.102",10088);//定义读取键盘数据的流对象BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));//定义目的,将数据写入socket输出流,发给服务器BufferedWriter bufout = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); //PrintWriter out = new PrintWriter(s.getOutputStream(),true); //定义一个socket读取流,读取服务端返回的信息。 BufferedReader bufin = new BufferedReader(new InputStreamReader(s.getInputStream()));String line = null;while((line=bufr.readLine())!=null){if("over".equals(line))break;bufout.write(line);bufout.newLine();bufout.flush();//out.println(line);String str = bufin.readLine();System.out.println("Server:"+str);}bufr.close();s.close();}}class TCPS3{public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10088); Socket s = ss.accept();String ip = s.getInetAddress().getHostAddress();System.out.println(ip+".....connect"); //读取socket读取流中的数据BufferedReader bufin = new BufferedReader(new InputStreamReader(s.getInputStream()));//目的,socket输出流,将大写数据写入到socket输出流,并发送给客户端。  BufferedWriter bufout = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); //PrintWriter out = new PrintWriter(s.getOutputStream(),true);  String line = null;while ((line=bufin.readLine())!=null){System.out.println(line);bufout.write(line.toUpperCase());bufout.newLine();bufout.flush();//out.println(line.toUppCase());}s.close();ss.close();}}
代码演示四:
TCP上传文件(使用IO字符流)
把文件从客户端传到服务器端上。
容易出现的问题:没有客户端上传完后,文件结束标记,服务器无法停止连接Socket连接。

import java.io.*;import java.net.*;class  TCPC4{public static void main(String[] args) throws Exception{Socket s = new Socket("192.168.1.102",11000);BufferedReader bufr = new BufferedReader(new FileReader("IPDemo.java"));PrintWriter out = new PrintWriter(s.getOutputStream(),true);String line= null;while ((line=bufr.readLine())!=null){out.println(line);}s.shutdownOutput();BufferedReader bufin= new BufferedReader(new InputStreamReader(s.getInputStream()));String str = bufin.readLine();System.out.println(str);bufr.close();s.close();}}class  TCPS4{public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(11000);Socket s = ss.accept();String ip = s.getInetAddress().getHostAddress();System.out.println(ip+"....connect");BufferedReader bufin = new BufferedReader(new InputStreamReader(s.getInputStream()));PrintWriter out = new PrintWriter(new FileWriter("copy.txt"),true);String line = null;while ((line=bufin.readLine())!=null){out.println(line);}PrintWriter pw = new PrintWriter(s.getOutputStream(),true);pw.println("上传成功!");out.close();s.close();ss.close();}}

TCP传输的两个问题:
①客户端与服务端交互时同时阻塞,当客户端和服务端有多个阻塞方法时,如果使用缓冲区读取每行,没有刷新和换行,会导致同时阻塞;
②定义结束标记:定义结束标记的方法:定义“over“这样的字符标记,或者盖时间标记,或者使用socket的shutdownOutput和shutdownInput方法(建议使用)。
代码演示五:
 需求:上传图片 
 客户端: 
1.服务端点 
2.读取客户端已有的图片数据 
3.通过socket的输出流将数据发给服务端。 
4.读取服务端反馈信息。 
5.关闭。
import java.net.*;import java.io.*;class PICC{public static void main(String[] args) throws Exception{Socket s =new Socket("192.168.1.102",10090);FileInputStream fis = new FileInputStream("L.jpg");OutputStream out = s.getOutputStream();byte[] buf = new byte[1024];int len = 0;while((len=fis.read(buf))!=-1){out.write(buf,0,len);}s.shutdownOutput();InputStream fin= s.getInputStream();byte[] bufin = new byte[1024];int in = fin.read(bufin);System.out.println(new String(bufin,0,in));fis.close();s.close();}}class PICS{public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10090);Socket s = ss.accept();String ip = s.getInetAddress().getHostAddress();System.out.println(ip+"....connected");InputStream in = s.getInputStream();FileOutputStream fout = new FileOutputStream("copy.jpg");byte[] buf = new byte[1024];int len= 0;while((len=in.read(buf))!=-1){fout.write(buf,0,len);}OutputStream out= s.getOutputStream();out.write("上传成功".getBytes());fout.close();s.close();ss.close();}}

TCP客户端并发访问:客户端并发访问服务器时,把服务端的处理代码封装在Runnable实现子类的run方法中,并把服务器获得的socket对象传递给该实现子类的构造函数,服务端通过while循环启动多个线程,对每个客户端请求进行并发处理,这也是一个服务器的基本原理;
import java.net.*;import java.io.*;class PICC1{public static void main(String[] args) throws Exception{if (args.length!=1){System.out.println("请选择要上传的图片");return ;}File file= new File(args[0]);if(!(file.exists()&&file.isFile())){System.out.println("图片不存在或不是图片文件");return ;}if(!file.getName().endsWith(".jpg")){System.out.println("图片格式错误,请选择jpg格式图片");return ;}if (file.length()>1024*1024*3){System.out.println("文件过大,上传失败");return ;}Socket s =new Socket("192.168.1.102",10090);FileInputStream fis = new FileInputStream(file);OutputStream out = s.getOutputStream();byte[] buf = new byte[1024];int len = 0;while((len=fis.read(buf))!=-1){out.write(buf,0,len);}s.shutdownOutput();InputStream fin= s.getInputStream();byte[] bufin = new byte[1024];int in = fin.read(bufin);System.out.println(new String(bufin,0,in));fis.close();s.close();}}/* 服务端:  这个服务端有个局限性,当A客户端连接上以后,被服务端获取到,服务端执行具体流程。 这时B客户端连接,只有等待。因为服务端还没有处理完A客户端的请求。还没有循环回来 执行下次accept方法。所以,暂时获取不到B客户端对象。那么为了可以让多个客户端 同时并发访问服务端。那么服务端最好就是将每个客户端封装到一个单独的线程中去。这 样就可以同时处理多个客户端请求。如何定义线程?只要明确了每一个客户端要在服务端 执行的代码即可。将该代码存入run方法中。  */  class PICThread implements Runnable{private Socket s;PICThread(Socket s){this.s= s;}public void run(){String ip = s.getInetAddress().getHostAddress();int c = 0;try{System.out.println(ip+"...已连接");InputStream in = s.getInputStream();File file= new File(ip+".jpg");while(file.exists())file= new File(ip+"("+(c++)+")"+".jpg");FileOutputStream fout = new FileOutputStream(file);byte[] buf = new byte[1024];int len= 0;while((len=in.read(buf))!=-1){fout.write(buf,0,len);}OutputStream out= s.getOutputStream();out.write("上传成功".getBytes());fout.close();s.close();}catch (Exception e){throw new RuntimeException(ip+"上传失败");}}}class PICS1{public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10090);while(true){Socket s = ss.accept();new Thread(new PICThread(s)).start();}}}
练习:
客户端通过键盘录入用户名: 
服务端对这个用户名进行校验。 
 
如果该用户存在,在服务器端显示***,已登录。 
并在客户端显示:***,欢迎光临。 
 
如果该用户不存在,在服务器端显示 ***,尝试登陆 
并在客户端显示 ***,该用户不存在。 
 
最多就登陆三次。 
import java.io.*;  import java.net.*;class LOGINC{public static void main(String[] args) throws Exception {Socket s = new Socket("192.168.1.102",11000);BufferedReader bfr= new BufferedReader(new InputStreamReader(System.in));PrintWriter out = new PrintWriter(s.getOutputStream(),true);BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));for(int x= 0;x<3;x++){String line= bfr.readLine();if(line==null)break;out.println(line);String info = in.readLine();System.out.println("info:"+info);if(info.contains("欢迎"))break;}bfr.close();s.close();}}class LOGINT implements Runnable{private Socket s;LOGINT(Socket s){this.s= s;}public void run(){String ip = s.getInetAddress().getHostAddress();System.out.println(ip+"......已连接");try{for (int x=0;x<3 ;x++ ){BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream()));String name = in.readLine();if (name==null)break;BufferedReader bufr =new BufferedReader(new FileReader("log.txt"));                  PrintWriter out = new PrintWriter(s.getOutputStream(),true); boolean flag = false;String line=null;while((line=bufr.readLine())!=null){if(line.equals(name)){flag = true;break;}}if(flag){System.out.println(name+"已登录");out.println(name+"欢迎光临");break;}else{System.out.println(name+"...尝试登陆");out.println(name+"..用户名不存在");}}s.close();}catch (Exception e){throw new RuntimeException(ip+"...登陆失败");}}}class LOGINS{public static void main(String[] args) throws Exception {ServerSocket ss = new ServerSocket(11000);while (true){Socket s = ss.accept();new Thread(new LOGINT(s)).start();}}}

URL:代表一个统一资源定位符,是指向互联网资源的指针,资源可以是简单的文本或目录,也可以是更为复杂对象的引用,如对数据库或搜索引擎的查询;
常用方法:
①int getDefaultPort(): 获取与此URL关联协议的默认端口;
②String getFile(): 获取此URL的文件名;
③String getHost(): 获取此URL的主机名;
④String getPath():或取此URL的路径;
⑤int getPort(): 获取此URL的端口号;
⑥ String getProtocol(): 获取此URL的协议名称;
⑦String getQuery(): 获取此URL的查询部分;
代码演示:
import java.net.*;  class  URLDemo  {      public static void main(String[] args) throws Exception      {          //URL url=new URL("http://192.168.1.13:11000/myweb/demo.html");          URL url=new URL("http://192.168.1.13:11000/myweb/demo.html?name=haha&age=30");          System.out.println("getProtocol():"+url.getProtocol()); //http                    System.out.println("getHost():"+url.getHost());//192.168.1.13          System.out.println("getDefaultPort():"+url.getDefaultPort());//80,如果关联的协议没有默认的端口,则值为-1;          System.out.println("getPort():"+url.getPort()); //  11000,如果没有设置则为-1;          System.out.println("getPath():"+url.getPath());// /myweb/demo.html          System.out.println("getFile():"+url.getFile());///myweb/demo.html?name=haha&age=30          System.out.println("getQuery():"+url.getQuery());//name=haha&age=30        /*  int port = url.getPort();         if(port==-1)             port =80;         getPort() = -1     */      }  }  
URLConnection:作用类似于socket,其实内部封装了socket,所以可以获取网络输入输出流,通过URL和URLConnection可以方便的对应用层网络数据进行读取和操作;
代码演示
import java.net.*;  import java.io.*;    class URLConnectionDemo   {      public static void main(String[] args) throws Exception      {          URL url=new URL("http://192.168.1.13:8080/myweb/demo.html");         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));        }  }

自定义图形化界面浏览器
import java.awt.*;  import java.awt.event.*;  import java.io.*;  import java.net.*;  class  MyIEByGUI  {      private Frame f;      private TextField tf;      private Button but;      private TextArea ta;        private Dialog d;      private Label lab;      private Button okBut;        MyIEByGUI()      {          init();      }      public void init()      {          f = new Frame("My IE");          f.setBounds(300,100,500,400);          f.setLayout(new FlowLayout());            tf = new TextField(40);          but = new Button("转到");          ta = new TextArea(20,50);            d = new Dialog(f,"提示信息-self",true);          d.setBounds(400,200,240,200);          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);        }      public void myEvent()      {          but.addActionListener(new ActionListener()          {              public void actionPerformed(ActionEvent e)              {                  try                  {                      showWebPage();                    }                  catch (Exception ex)                  {                  }                                }          });          tf.addKeyListener(new KeyAdapter()          {              public void keyPressed(KeyEvent e)//用keyTyped事件不成功              {                  if(e.getKeyCode()==KeyEvent.VK_ENTER)                  {                      try                      {                          showWebPage();                        }                      catch (Exception ex)                      {                      }                                        }              }            });          okBut.addActionListener(new ActionListener()          {              public void actionPerformed(ActionEvent e)              {                  d.setVisible(false);              }          });          d.addWindowListener(new WindowAdapter()          {              public void windowClosing(WindowEvent e)              {                  d.setVisible(false);              }          });          f.addWindowListener(new WindowAdapter()          {              public void windowClosing(WindowEvent e)              {                  System.exit(0);              }          });                }      private void showWebPage() throws Exception      {          ta.setText("");                    //http://192.168.1.13:8080/myweb/demo.html          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 dir = url.substring(index2);          //ta.setText(url);          ta.setText(port+","+null);          //建立Socket客户端          Socket s = new Socket(host,port);          //发送请求消息头          PrintWriter out = new PrintWriter(s.getOutputStream(),true);//别忘了加true          out.println("GET "+dir+" HTTP/1.1");          out.println("Accept: */*");          out.println("Accept-Language: zh-cn");          out.println("Host: 192.168.1.13:11000");          out.println("Connection: Keep-Closed");          out.println();//记得一定要加空行          out.println();            BufferedReader bufr =               new BufferedReader(new InputStreamReader(s.getInputStream()));          String line = null;          while((line=bufr.readLine())!=null)          {              ta.append(line+"\r\n");          }          s.close();        }        public static void main(String[] args)       {          new MyIEByGUI();      }  }  private void showWebPage() throws Exception  {      //使用URL和URLConnection对showWebPage改写。      //很明显,这两个封装的应用层对象使用起来更方便简洁      ta.setText("");           String urlPath =tf.getText();             URL url=new URL(urlPath);      URLConnection conn = url.openConnection();      //System.out.println(conn);      InputStream in = conn.getInputStream();      byte [] buf =new byte[1024];      int len = in.read(buf);      ta.setText(new String(buf,0,len));  }

域名解析:用IP地址登陆网站,数字不好记忆,习惯用主机名,如www.baidu.com,从主机名到获得该主机名对应的IP地址的过程,就是域名解析,它一般是DNS服务器完成的;
域名解析步骤大致分为2步:
①查找本地的IP地址和主机名映射表,如果存在映射,则使用本机映射,如:127.0.0.1和localhost的对应关系就在这个映射表中,通过对映射文件进行配置可以实现一些功能,如:将常用网站配置在表中,这样速度快些,还可以屏蔽过滤一些垃圾网站;
②如果第一步没有找到,就会去设置的DNS服务器查找,找到对应的IP地址,获取地址后,再返回给本机IP地址,本机再通过IP地址链接上想要访问的网站。














原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 20岁欠了10万怎么办 我赌博欠了10万怎么办 孩子见到生人不爱说话怎么办 18岁了个子矮小怎么办 1岁宝宝个子矮70怎么办 喋血街头2进监狱怎么办 360云盘收费了怎么办 头脑不清醒晕沉怎么办 一岁宝宝还不会走路怎么办 2岁宝宝受凉呕吐怎么办 3岁宝宝受凉呕吐怎么办 1岁宝宝受凉呕吐怎么办 3岁宝宝着凉呕吐怎么办 宝宝一进食就吐怎么办 宝宝吃什么都吐怎么办 一岁宝宝吃着了怎么办 宝宝吃了就吐怎么办 图书借阅证丢了怎么办 苹果6手机掌阅怎么办 厨房墙砖颜色深怎么办 炉石传说被盗号怎么办 炉石传说号忘了怎么办 手机丢失了微信怎么办 眼睛疼红血丝多怎么办 lol更新速度3kb怎么办 苹果6s玩游戏卡怎么办 微博手机号换了怎么办 微博字数超了怎么办 海外玩传奇很卡怎么办 再审期限超6个月怎么办 肠粉蒸出来太粘怎么办 微信订阅号没了怎么办 映美620k不进纸怎么办 属虎的带了貔貅怎么办 属龙的不能带金怎么办 这段时间运气不好怎么办 两年运气特别差怎么办 玩手机麻将老输怎么办 打四川麻将老输怎么办 网上打麻将老输怎么办 手机打麻将老输怎么办