### Java网络编程 Web 编程在整个 Java 开发中占据了很大一部分内容,所谓 Web 编程就是编写程序运行在同一网络下的两个终端上,使得它们之间可以进行数据传输。 计算机网络就是通过硬件设施、传输媒介把分散在不同地区的计算机进行连接,形成一个资源共享和数据传输的网络系统。 两台终端通过网络进行连接时,需要遵守一定的规则,这个规则就是网络协议(network rotocol),网络协议主要由3个特征组成: - 语法:数据信息的结构。 - 语义:描述请求、动作和响应。 - 同步:动作的实现顺序。 网络通信协议有 TCP/IP 协议,IPX/SPX 协议,NetBEUI协议,最常用的协议是 TCP/IP 协议,同时该协议是分层的,分层的优点: - 各层之间相互独立,互不干扰。 - 维护性、扩展性好。 - 有利于系统的标准化。 TCP/IP 协议可以分为4层,从上到下依次为应用层、传输层、网络层和网络接口层。 应用层(application layer)是整个体系结构中的顶层,通过应用程序之间的数据交互完成网络应用。 传输层(transport layer)为两台终端中的应用程序之间的数据交互提供数据传输服务。 网络层(network layer)也叫 IP 层,负责为网络中不同终端提供通信服务。 网络接口层(network interface layer)包括数据链路层(data link layer)和物理层(physical layer),数据链路层的作用是为两台终端的数据传输提供链路协议;物理层是指光纤、电缆等能够传递信号的各种物理介质。 终端A正在和终端B通过网络进行通信,整个数据的传输流程是终端A-》应用层-〉传输层-》网络层-〉数据链路层-》网络层-〉传输层-》应用层-〉终端B。 ###IP和端口 IP:互联网中的每台终端设备都有一个唯一的标示,网络中的请求可以根据这个标示找到具体的计算机,这个唯一标示就是IP地址(Internel Protocol)。 192.168.11.102 IP地址=网络地址+主机地址,网络地址的作用是找到主机所在的网络,主机地址的作用是找到网络中的主机。IP地址可以分为5类,各类地址可以使用的IP数量不同,具体范围如下。 A类 1.0.0.1~126.255.255.254 B类 128.0.0.1~191.255.255.254 C类 192.0.0.1~223.255.255.254 D类 224.0.0.1~239.255.255.254 E类 240.0.0.1~255.255.255.254 实际开发中不需要记录本机的IP地址,可以使用127.0.0.1或者localhost来标示本机IP地址,Java 中有专门的类来描述IP地址,这个类是 java.net.InetAddress,常用方法如下。 public static InetAddress getLocalHost() 获取本地主机的InetAddress对象 public static InetAddress getByName(String host) 通过主机名创建InetAddress对象 String getHostName() 获取主机名称 public String getHostAddress() 获取主机IP地址 public static InetAddress getByAddress(String host,byte[] addr) 通过主机名称和IP地址创建InetAddress对象 public static InetAddress getByAddress(byte[] addr) 通过IP地址创建Address对象 ```java import java.net.InetAddress; import java.net.UnknownHostException; public class Test { public static void main(String[] args) { InetAddress inetAddress; try { inetAddress = InetAddress.getLocalHost(); System.out.println(inetAddress.getHostName()); System.out.println(inetAddress.getHostAddress()); inetAddress = InetAddress.getByName("127.0.0.1"); System.out.println(inetAddress); inetAddress = InetAddress.getByName("localhost"); System.out.println(inetAddress); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } ``` ### 端口 如果把IP比作一栋大厦的地址,那么端口(port)就是不同房间的门牌号,IP地址需要和端口结合使用,请求根据"IP地址+端口"就可以准确地找到互联网中接收请求的服务端。URL:localhost:3306。 ### URL和URLConnection - URL 通常所讲的网络资源实际就是指网络中真实存在的某个实体,比如一段文字、一张图片、一段视频、一首音频等,如果需要在网络中获取资源,可以用URI(Uniform Resource Identifier)统一资源定位符指向目标实体,URI的作用是用特定的语法来表示某个网络资源,Java 中专门封装了一个类用来描述URI,java.net.URI。 使用URI的实例化对象,可以用面向对象的方式来管理网络资源,如获取主机地址、端口等,在本机部署服务,通过URI读取该服务中的某个资源。 ```java import java.net.URI; import java.net.URISyntaxException; public class Test3 { public static void main(String[] args) { try { URI uri = new URI("http://localhost:8080/mytest.jsp"); System.out.println(uri.getHost()); System.out.println(uri.getPort()); System.out.println(uri.getPath()); } catch (URISyntaxException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } ``` - URL URL 和 URI 有什么区别?URL(Uniform Resource Locator)是统一资源位置,在 URI 的基础上进行了扩充,在定位资源的同时还提供了对应的网络地址,Java 也对 URL 进行了封装,java.net.URL。 public URL(String protocol,String host,int port,String file) 根据协议、IP地址、端口号、资源名称获取URL对象 public final InputStream() 获取输入流对象 ```java import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.net.MalformedURLException; import java.net.URL; public class Test3 { public static void main(String[] args) { InputStream inputStream = null; Reader reader = null; BufferedReader bufferedReader = null; try { URL url = new URL("http","127.0.0.1",8080,"/login.jsp"); inputStream = url.openStream(); reader = new InputStreamReader(inputStream); bufferedReader = new BufferedReader(reader); String str = null; while((str = bufferedReader.readLine())!=null) { System.out.println(str); } } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { bufferedReader.close(); reader.close(); inputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } ``` 同时也可以通过URL获取资源的其他信息,如主机地址、端口等。 ```java import java.net.MalformedURLException; import java.net.URL; public class Test4 { public static void main(String[] args) { try { URL url = new URL("http","127.0.0.1",8080,"/login.jsp"); System.out.println(url.getHost()); System.out.println(url.getPort()); System.out.println(url.getPath()); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } ``` ### URLConnection URLConnection 用来描述URL指定资源的连接,是一个抽象类,常用的子类有 HttpURLConnection,URLConnection 底层是通过 HTTP 协议来处理的,它定义了访问远程网络资源的方法,通过URLConnection可以获取到 URL 资源的相关信息。 public int getContentLength() 返回资源的长度,int 类型 public long getContentLengthLong() 返回资源的长度,long 类型 public String getContentType() 返回资源的类型 public abstract void connect() 判断连接的状态 public InputStream getInputStream() 获取输入流对象 ```java import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; public class Test5 { public static void main(String[] args) { try { URL url = new URL("http://localhost:8080/login.jsp"); URLConnection urlConnection = url.openConnection(); System.out.println(urlConnection); System.out.println(urlConnection.getURL()); System.out.println(urlConnection.getContentLength()); System.out.println(urlConnection.getContentLengthLong()); System.out.println(urlConnection.getContentType()); InputStream inputStream = urlConnection.getInputStream(); Reader reader = new InputStreamReader(inputStream); BufferedReader bufferedReader = new BufferedReader(reader); String str = null; while((str = bufferedReader.readLine())!=null) { System.out.println(str); } } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } ``` ### TCP协议 Socket 类,通过 Socket 可以在服务端和客户端之间建立起可靠的连接。Socket 表示客户端,服务端使用 ServerSocket来表示,ServerSocket也是一个类,ServerSocket和Socket都存放在java.net包中。具体的思路是在服务端创建ServerSocket对象,然后通过该对象的accept()方法接收到若干个表示客户端的Socket对象。
Test.java
import java.net.InetAddress; import java.net.UnknownHostException; public class Test { public static void main(String[] args) { InetAddress inetAddress; try { inetAddress = InetAddress.getLocalHost(); System.out.println(inetAddress.getHostName()); System.out.println(inetAddress.getHostAddress()); inetAddress = InetAddress.getByName("127.0.0.1"); System.out.println(inetAddress); inetAddress = InetAddress.getByName("localhost"); System.out.println(inetAddress); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
Test2.java
import java.net.URI; import java.net.URISyntaxException; public class Test2 { public static void main(String[] args) { try { URI uri = new URI("http://localhost:8080/login.jsp"); System.out.println(uri.getHost()); System.out.println(uri.getPort()); System.out.println(uri.getPath()); } catch (URISyntaxException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
Test3.java
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.net.MalformedURLException; import java.net.URL; public class Test3 { public static void main(String[] args) { InputStream inputStream = null; Reader reader = null; BufferedReader bufferedReader = null; try { URL url = new URL("http","127.0.0.1",8080,"/login.jsp"); inputStream = url.openStream(); reader = new InputStreamReader(inputStream); bufferedReader = new BufferedReader(reader); String str = null; while((str = bufferedReader.readLine())!=null) { System.out.println(str); } } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { bufferedReader.close(); reader.close(); inputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
Test4.java
import java.net.MalformedURLException; import java.net.URL; public class Test4 { public static void main(String[] args) { try { URL url = new URL("http","127.0.0.1",8080,"/login.jsp"); System.out.println(url.getHost()); System.out.println(url.getPort()); System.out.println(url.getPath()); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
Test5.java
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; public class Test5 { public static void main(String[] args) { try { URL url = new URL("http://localhost:8080/login.jsp"); URLConnection urlConnection = url.openConnection(); System.out.println(urlConnection); System.out.println(urlConnection.getURL()); System.out.println(urlConnection.getContentLength()); System.out.println(urlConnection.getContentLengthLong()); System.out.println(urlConnection.getContentType()); InputStream inputStream = urlConnection.getInputStream(); Reader reader = new InputStreamReader(inputStream); BufferedReader bufferedReader = new BufferedReader(reader); String str = null; while((str = bufferedReader.readLine())!=null) { System.out.println(str); } } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }