Java 网络编程基础
文章来源:https://mp.weixin.qq.com/s/xQJ2iR8iGgj-Cs5tq45qdA
网络可以使不同物理位置上的计算机达到资源共享和数据传输的目的,网络编程主要就是面向底层数据的传输。Java 中提供了专门的网络编程程序包 java.net。
网络编程的几个概念:
IP 地址:互联网上的每一台计算机都有一个唯一的标记来表示,这个标记就是 IP 地址。
IP 地址分为 5 类:A 类分配给政府机构,B 类分配给一定规模的公司,C 类分配给任何有需要的人,D 类用于组播,E 类用于实验。
IP 地址的范围表如下:
序号 | 地址分类 | 地址范围 |
---|---|---|
1 | A 类地址 | 1.0.0.1 ~ 126.255.255.254 |
2 | B 类地址 | 128.0.0.1 ~ 191.255.255.254 |
3 | C 类地址 | 192.0.0.1 ~ 223.255.255.254 |
4 | D 类地址 | 224.0.0.1 ~ 239.255.255.254 |
5 | E 类地址 | 240.0.0.1 ~ 255.255.255.254 |
其中,127.x.x.x 是保留地址,一般 127.0.0.1 表示本机地址。
端口号:端口号用于区分计算机上的软件,不同软件的端口号不同,1024 以下的端口号一般自定义程序不使用,作为预留端口,比如 http 的 80 端口,ftp 的 21 端口等。端口号的取值范围为:0 ~ 65535。
资源定位: URI(Uniform Resource Identifier)统一资源标识符,用来标识一个资源,URL(Uniform Resource Locator )统一资源定位符,用于标示网络资源的位置,URL 是一种具体的 URI。
IP 操作的两个类:
1、InetAddress 类
InetAddress 类没有封装端口,可以获取 IP 和计算机名
@Test
public void testInetAddress() throws UnknownHostException {
// 使用getLocalHost()方法创建InetAddress对象
InetAddress netAddress = InetAddress.getLocalHost();
// 获取本机ip
System.out.println(netAddress.getHostAddress());
// 获取本机计算机名
System.out.println(netAddress.getHostName());
// 根据域名使用getByName方法创建InetAddress对象
netAddress = InetAddress.getByName("www.baidu.com");
// 返回 163服务器的ip:61.135.169.121
System.out.println(netAddress.getHostAddress());
// 输出:www.baidu.com
System.out.println(netAddress.getHostName());
// 根据ip使用getByName方法创建InetAddress对象
netAddress = InetAddress.getByName("61.135.169.121");
// 返回 baidu服务器的ip:61.135.169.121
System.out.println(netAddress.getHostAddress());
// 如果这个IP地址不存在或DNS服务器不允许进行IP地址和域名的映射,getHostName方法就直接返回这个IP地址
System.out.println(netAddress.getHostName());
}
运行结果:
192.168.1.1 JPM 61.135.169.125 www.baidu.com 61.135.169.121
2、InetSocketAddress 类
InetSocketAddress 类在 InetAddress 类的基础上增加了端口参数,可以可以指定端口。
@Test
public void testInetSocketAddress() throws UnknownHostException {
//InetSocketAddress类可以指定端口
InetSocketAddress netSocketAddress = new InetSocketAddress("www.baidu.com", 8080);
System.out.println(netSocketAddress.getHostName());
System.out.println(netSocketAddress.getPort());
InetAddress addr = netSocketAddress.getAddress();
System.out.println(addr.getHostAddress());
System.out.println(addr.getHostName());
}
运行结果:
www.baidu.com 8080 61.135.169.125 www.baidu.com
URL 操作示例:
URL 至少包含 4 个部分:协议、域名、端口、资源,下面通过一段代码来演示 URL 的使用。
@Test
public void testURL() throws IOException {
// 绝对路径构建URL
URL url = new URL("https://www.baidu.com:80/index.html?para=Java");
System.out.println("URL的协议:" + url.getProtocol());
System.out.println("URL的域名:" + url.getHost());
System.out.println("URL的端口:" + url.getPort());
System.out.println("URL的资源:" + url.getFile());
System.out.println("URL的参数:" + url.getQuery());
// 相对路径URL
url = new URL("https://www.baidu.com:80/aaa/");
url = new URL(url, "aaa.html");
System.out.println("URL的路径" + url.toString());
// URLConnection是封装访问远程网络资源的类,可以通过它建立与远程服务器的连接,检查远程资源的一些属性
URL url1 = new URL("https://www.baidu.com");
URLConnection urlConn = url1.openConnection();
// 取得内容大小
System.out.println(urlConn.getContentLength());
// 取得内容类型
System.out.println(urlConn.getContentType());
// URLEncoder编码,URLDecoder解码
String msg = "你好,中国";
String msgEncod = URLEncoder.encode(msg, "utf-8");
System.out.println(msg + " 编码之后:" + msgEncod);
String msgDecod = URLDecoder.decode(msg, "utf-8");
System.out.println(msgEncod + " 解码之后:" + msgDecod);
}
运行结果:
URL的协议:https URL的域名:www.baidu.com URL的端口:80 URL的资源:/index.html?para=Java URL的参数:para=Java URL的路径https://www.baidu.com:80/aaa/aaa.html 2443 text/html 你好,中国 编码之后:%E4%BD%A0%E5%A5%BD%EF%BC%8C%E4%B8%AD%E5%9B%BD %E4%BD%A0%E5%A5%BD%EF%BC%8C%E4%B8%AD%E5%9B%BD 解码之后:你好,中国
获取一个 URL 资源的内容
通过 URL 结合 IO 流获取一个 URL 资源的内容。
@Test
public void test() throws IOException {
URL url = new URL("https://www.baidu.com"); // 获取百度主页的资源
// 通过流获取网络资源
InputStream is = url.openStream();
byte[] bytes = new byte[1024];
int len = 0;
while ((len = is.read(bytes)) != -1) {
System.out.println(new String(bytes, 0, len));
}
is.close();
// 以上代码获取到的内容会有乱码,可以使用转换流InputStreamReader来指定utf-8编码
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream(), "utf-8"));
String msg = null;
while ((msg = br.readLine()) != null) {
System.out.println(msg);
}
br.close();
// 以上代码解决了乱码的问题,我们也可以通过io流把获取到的内容输出到一个文件中
BufferedReader br1 = new BufferedReader(new InputStreamReader(url.openStream(), "utf-8"));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("baidu.html"), "utf-8"));
String msg1 = null;
while ((msg1 = br1.readLine()) != null) {
bw.append(msg1);
bw.newLine();
}
bw.flush();
bw.close();
br1.close();
}
以上代码可以获取到一个 URL 资源的内容,结合正则表达式可以对网站内容进行分析。