Java网络编程详解——网络基础知识介绍、IP和端口介绍、URL和URLConnection介绍

网络基础知识——计算机网络介绍、通信协议与网络结构模型

一、 计算机网络就是把分布在不同地理区域的计算机与专门的外部设备,用通信线路互连成一个网络系统,从而使众多的计算机可以互相传递信息,共享资源。

  • 计算机网络通常按照规模大小和延伸范围分类,常见的划分为:局域网(LAN)、城域网(MAN)、广域网(WAN)。Internet可以视为世界上最大的广域网。

二、计算机网络中实现通信必须有一些约定,这些约定被称为通信协议。通信协议通常由三部分组成:①语义部分:用于决定双方对话的类型;②语法部分:用于决定双方对话的格式;③变换规则:用于决定通信双方的应答关系。

  • IP协议是一种非常重要的通信协议,又称互联网协议。是支持网间互联的数据报协议。提供网间连接的完善功能,包括IP数据报规定互联网络范围内的地址格式。
  • 经常与IP协议放在一起的还有TCP协议,即传输控制协议。它规定一种可靠的数据信息传递服务。
  • 虽然IP和TCP这两个协议功能不尽相同,也可以分开单独使用,但它们是在同一个时期作为一个协议来设计的,并且在功能上也是互补的。因此实际使用中常常把这两个协议统称为TCP/IP协议。

三、按TCP/IP协议模型,网络通常被分为一个四层模型,这个四层模型和OSI(开放式系统互连参考模式)七层模式有大致的对应关系。

OSI分层模型TCP/IP分层模型
应用层应用层
表示层
会话层
传输层传输层
网络层网络层
数据链路层物理+数据链路
物理层

IP地址和端口号

当一个程序需要发送数据时,需要指定目的地的IP地址和端口,只有指定了正确的IP地址和端口号,计算机网络才能将数据送给该IP地址和端口所对应的程序。

一、IP地址

IP地址用于唯一地标识网络中的一个通信实体,这个通信实体既可以是一台主机,也可以是一台打印机,或者是路由器的某一个端口。

  • 在基于IP协议网络中传输的数据包,都必须使用IP地址来进行标识。每个被传输的数据包有一个源IP地址和一个目的IP地址,当该数据包在网络中进行传输时,这两个地址要保持不变,以确保网络设备总能根据确定的IP地址,将数据包从源通信实体送往指定的目的通信实体。
  • IP地址是数字型的,IP地址是一个32位的整数。为了便于记忆,通常把它分为4个8位的二进制数,每8位之间用圆点隔开。每个8位整数可以转换成一个0~255的十进制整数,因此日常看到的IP地址的格式形如: 222.247.82.201

IP地址被分成了A、B、C、D、E五类,每个类别的网络标识和主机标识各有规则:
A类: 1.0.0.1 — 127.255.255.254

  • 10.X.X.X是私有地址(私有地址就是在互联网上不使用,而被用在局域网络中的地址)
  • 127.X.X.X是保留地址,用做循环测试用的。

B类: 128.0.0.1 — 191.255.255.254

  • 172.16.0.0 — 172.31.255.255是私有地址
  • 169.254.X.X是保留地址。

C类: 192.0.0.1 — 223.255.255.254

  • 192.168.X.X是私有地址

D类: 224.0.0.1 — 239.255.255.254

E类: 240.0.0.1 — 247.255.255.254

IP地址的组成: IP地址 = 网络号码+主机地址

  • A类IP地址:第一段号码为网络号码,剩下的三段号码为本地计算机的号码 : 256256256 — 16777216
  • B类IP地址:前二段号码为网络号码,剩下的二段号码为本地计算机的号码 : 256*256 — 65536
  • C类IP地址:前三段号码为网络号码,剩下的一段号码为本地计算机的号码 : 256

查看本机IP:ipconfig

查看网络是否有问题 ping+IP地址

  • ping 127.0.0.1(本机回环地址)
  • ping 127.0.0.1(本机回环地址)

二、端口

IP地址用于唯一地标识网络上的一个通信实体,但一个通信实体可以有多个通信程序同时提供网络服务,此时还需要使用端口。

  • 端口是一个16位的整数,用于表示数据交给哪个通信程序处理。因此,端口就是应用程序与外界交流的出入口。这里的端口是指一种抽象的软件结构,包括一些数据结构和I/O缓冲区。
  • 不同应用程序处理不同端口上的数据,同一台机器上不能有两个程序使用同一个端口。

端口号从0~65535,通常将它分为三类:

  • 公认端口: 从0到1023, 它们紧密绑定一些特定的服务;
  • 注册端口: 从1024到49151, 它们它们松散地绑定一些服务。应用程序通常应该使用这个范围内的端口;
  • 动态和/或私有端口: 从49152到65535, 这些端口是应用程序使用的动态端口,应用程序一般不会主动使用这些端口。

Java中网络相关的API

一、InetAddress

Java提供了InetAddress类来代表IP地址,InetAddress下还有两个子类:Inet4Address、Inet6Address,分别代码表IPv4地址和IPv6地址。

InetAddress类没有构造器,通过静态方法获取InetAddress实例

  1. public static InetAddress getByName(String host): 根据主机获取对应的InetAddress对象。
  2. public static InetAddress getByAddress(byte[] addr): 根据原始IP地址获取对应的InetAddress对象。
  3. public static InetAddress getLocalHost(): 获取本机IP地址对应的InetAddress对象。

InetAddress提供的常用方法

  1. public String getHostName(): 获取此IP地址的主机名
  2. public String getHostAddress(): 返回此InetAddress实例对应的IP地址字符串。
  3. public boolean isReachable(int timeout): 测试是否可以到达该地址。因为防火墙和服务器配置可能阻塞请求,使得它在访问某些特定的端口时处于不可到达状态。如果可以获取权限,典型的实现是使用ICMP ECHO REQUEST。否则它将试图在目标主机的端口7(Echo)上建立连接。

二、URLDecoder和URLEncoder

URLDecoder和URLEncoder用于实现普通字符串和application/x-www-form-urlencoded MIME 字符串之前的相互转换。

http的get请求包含中文时,在url地址后对应的中文参数会被转换为形如"%XX%XX%XX%XX%XX%XX"的字符串,这种字符串就被称为是application/x-www-form-urlencoded MIME字符串。

1. URLDecoder
public static String decode(String s, String enc): 静态方法,将参数s表示的application/x-www-form-urlencoded MIME字符串,通过enc指定的编码集,转换为普通字符串。

2. URLEncoder
public static String encode(String s, String enc): 静态方法,将参数s表示的普通字符串,通过enc指定的编码集,转换为application/x-www-form-urlencoded MIME字符串。

仅包含西欧字符的普通字符串application/x-www-form-urlencoded MIME字符串无须转换,而包含中文字符的普通字符串则需要转换,转换方法是每个中文字符占两个字节,每个字节可以转换成两个十六进制的数字 ,所以每个中文字符将转换为"%XX%XX"的形式。

采用不同的字符集,每个中文字符对应的字节数并不完全相同,所以使用URLEncoder和URLDecoder进行转换时需要指定字符集。

三、URL、URLConnection和HttpURLConnection

URL介绍和相关API方法

URL(Uniform Resource Locator)对象表示统一资源定位器,它是指向互联网资源的指针。

  • 通常情况下,URL由协议名、主机、端口和资源组成,满足格式:protocol://host:port/resourcePath

JDK中还提供了一个URI(Uniform Resource Identifiers)类,表示一个统一资源标识符,Java中的URI不能用于定位任何资源,它的唯一作用就是解析。与此对应的是,URL包含一个可打开到达该资源的输入流,可以将URL理解成URI的特例。

  • URL的常用API:
    public URL(String spec): 使用URL格式的字符串形式创建URL对象。
    public URL(String protocol, String host, int port, String file): 使用给定的协议、主机、端口和资源创建URL对象。
    public URL(String protocol, String host, String file): 使用给定协议的默认端口,和给定的资源创建URL对象。

    public String getFile(): 获取该URL的资源名。
    public String getHost(): 获取该URL的主机名。
    public String getPath(): 获取该URL的路径名。
    public int getPort(): 获取该URL的端口号。
    public String getProtocol(): 获取该URL的协议名称。
    public String getQuery(): 获取该URL的查询字符串部分。

    public URLConnection openConnection():返回一个URLConnection对象,它代表了与URL所引用的远程对象的连接。
    public final InputStream openStream():打开与此URL的连接,并返回一个用于读取该URL资源的InputStream。通过调return openConnection().getInputStream();实现。

URLConnection和HttpURLConnection

1. URLConnection

URL的openConnection()方法返回一个URLConnection对象。URLConnection对象表示应用程序和URL之间的通信连接。程序可以通过URLConnection实例向该URL发送请求,读取URL引用的资源。

  • 通常创建一个和URL的连接,并发送请求,读取此URL引用的资源需如下几个步骤:

    1. 获取URL对象,通过调用URL对象的openConnection()方法来创建URLConnection对象;
    2. 设置URLConnection的参数和普通请求属性;
    3. 建立和远程资源的实际连接。如果只是发送GET方式的请求,则使用URLConnection的connect()方法建立和远程资源之间的实际连接即可;如果是发送POST方式的请求,则需要调URLConnection的getOutputStream()获取对应的输出流,通过输出流向远程资源发送POST方法的请求参数。
    4. 在远程资源变为可用之后,程序可以访问远程资源的头字段,或通过输入流读取远程资源的数据。
  • 在建立和远程资源的实际连接之前,程序可以通过如下方法来设置请求头字段。
    public void setAllowUserInteraction(boolean allowuserinteraction): 设置URLConnection对象的allowUserInteraction请求头字段值。
    public void setDoInput(boolean doinput): 设置URLConnection对象的doInput请求头字段值。
    public void setDoOutput(boolean dooutput): 设置URLConnection对象的doOutput请求头字段值。
    public void setIfModifiedSince(long ifmodifiedsince): 设置URLConnection对象的ifModifiedSince请求头字段值。
    public void setUseCaches(boolean usecaches): 设置URLConnection对象的useCaches请求头字段值。
    public void setRequestProperty(String key, String value): 设置通用的头字段。如setRequestProperty("accept", "*/*")
    public void addRequestProperty(String key, String value): 为请求头字段key增加value值。只是在key字段原有值的后面追加新的value值,并不会覆盖key字段原来的值。

  • 当远程资源可用之后,程序可以使用如下方法获取响应头字段的值,以及访问远程资源的内容。
    public Object getContent(): 获取该URLConnection的内容。
    public String getHeaderField(String name): 获取指定响应头字段的值。
    public InputStream getInputStream(): 返回该URLConnection对应的输入流,用于获取URLConnection响应的内容。
    public OutputStream getOutputStream(): 返回该URLConnection对应的输出流,用于向URLConnection发送请求参数。

  • 除了通过getHeaderFiled(String name)方法获取name指定的响应头字段值之外,Java还提供了如下方法用于获取常用的响应头字段的值。
    public String getContentEncoding(): 获取content-encoding响应头字段的值。
    public int getContentLength(): 获取content-length响应头字段的值。
    public String getContentType(): 获取content-type响应头字段的值。
    public long getDate(): 获取date响应头字段的值。
    public long getExpiration(): 获取expires响应头字段的值。
    public long getLastModified(): 获取last-modified响应头字段的值。

  • URLConnection的其他API方法
    abstract public void connect(): 用于建立实际的连接,一般在GET方法请求中用到。(POST方法请求调了getOutputStream,所以不需要再调connet方法)
    public void setConnectTimeout(int timeout): 用于在建立实际连接时,设置的超时时间,单位为ms。在设置时间内,没有连接成功,则会报SocketTimeoutException异常
    public void setReadTimeout(int timeout): 用于在读取InputStream输入流中的资源时,设置的超时时间,单位为ms。在设置时间内,没有读取到资源,则会报SocketTimeoutException异常。

  • 举例: 使用URLConnection实现GET请求

      /**
       * 向指定URL发送GET方法的请求
       * @param url 发送请求的URL
       * @param params 请求参数,请求参数应该是name1=value1&name2=value2的形式。
       * @return URL所代表远程资源的响应
       */
      public static String sendGet(String url, String params){
      	String result = "";
      	BufferedReader in = null;
      	try{
      		String urlName = url + "?" + params;
      		URL realUrl = new URL(urlName);
      		// 打开和URL之间的连接
      		URLConnection conn = realUrl.openConnection();
      		// 设置通用的请求属性
      		conn.setRequestProperty("accept", "*/*");
      		conn.setRequestProperty("connection", "Keep-Alive");
      		conn.setRequestProperty("user-agent",
      				"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
      		// 建立实际的连接
      		conn.connect();
      		// 获取所有响应头字段
      		Map<String, List<String>> map = conn.getHeaderFields();
      		// 遍历所有的响应头字段
      		for (String key : map.keySet()){
      			System.out.println(key + "--->" + map.get(key));
      		}
      		// 定义BufferedReader输入流来读取URL的响应
      		in = new BufferedReader(
      				new InputStreamReader(conn.getInputStream()));
      		String line;
      		while ((line = in.readLine()) != null){
      			result += "\n" + line;
      		}
      	}catch (Exception e){
      		System.out.println("发送GET请求出现异常!" + e);
      		e.printStackTrace();
      	}
      	// 使用finally块来关闭输入流
      	finally{
      		try{
      			if (in != null){
      				in.close();
      			}
      		}catch (IOException ex){
      			ex.printStackTrace();
      		}
      	}
      	return result;
      }
    
  • 举例: 使用URLConnection实现POST请求

    使用URLConnection发送POST请求必须设置setDoOutput(true)和setDoInput(true)。

     /**
      * 向指定URL发送POST方法的请求
      * @param url 发送请求的URL
      * @param params 请求参数,请求参数应该是name1=value1&name2=value2的形式。
      * @return URL所代表远程资源的响应
      */
     public static String sendPost(String url, String params){
     	PrintWriter out = null;
     	BufferedReader in = null;
     	String result = "";
     	try{
     		URL realUrl = new URL(url);
     		// 打开和URL之间的连接
     		URLConnection conn = realUrl.openConnection();
     		// 设置通用的请求属性
     		conn.setRequestProperty("accept", "*/*");
     		conn.setRequestProperty("connection", "Keep-Alive");
     		conn.setRequestProperty("user-agent",
     				"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
     		// 发送POST请求必须设置如下两行
     		conn.setDoOutput(true);
     		conn.setDoInput(true);
     		// 获取URLConnection对象对应的输出流
     		out = new PrintWriter(conn.getOutputStream());
     		// 发送请求参数
     		out.print(params);  // ②
     		// flush输出流的缓冲
     		out.flush();
     		// 定义BufferedReader输入流来读取URL的响应
     		in = new BufferedReader(
     				new InputStreamReader(conn.getInputStream()));
     		String line;
     		while ((line = in.readLine()) != null){
     			result += "\n" + line;
     		}
     	}catch (Exception e){
     		System.out.println("发送POST请求出现异常!" + e);
     		e.printStackTrace();
     	}
     	// 使用finally块来关闭输出流、输入流
     	finally{
     		try{
     			if (out != null){
     				out.close();
     			}
     			if (in != null){
     				in.close();
     			}
     		}
     		catch (IOException ex){
     			ex.printStackTrace();
     		}
     	}
     	return result;
     }
    

2. HttpURLConnection

HttpURLConnection是URLConnection的子类。HttpURLConnection在URLConnection的基础上做了进一步改进,增加了一些用于操作HTTP资源的方法。

  • HttpURLConnection一些特有的方法如下:
    public int getResponseCode(): 获取服务器的响应码。
    public String getResponseMessage(): 获取服务器的响应消息。
    public void setRequestMethod(String method): 设置发送HTTP请求的方式。
    public String getRequestMethod(): 获取发送HTTP请求的方式。

//TODO (HttpURLConnection实现文件下载示例、理解什么叫建立和远程资源的实际连接)
未完待续…

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值