jdk1.8版本,下载包地址:http://www.doc.canglaoshi.org

概念

为了解决通信制定的一套规则。Java号称是在Internet上的语言

  • java.net包 :java网络类库,可以实现无痛苦的连接。继承JVM虚拟机
  • JVM虚拟机:JDK,表示运行时的环境。查看路径:环境变量下JAVA_HOME + Path

终端输入:

  • java:用来检测是否安装了JDK。
  • java -version:用来检测JDK的版本。

java.net包

  • Internet地址(InetAddress)用来实现IP协议
    OSI网络模型:物理层1(含电话网) -> 数据链路层2 -> 网络层3(含java.net、IP协议) -> 传输层4(含HTTP/HTTPS协议、UDP【无连接】/TCP【连接】协议) -> 会话层5 -> 表示层6 -> 应用层7(含FTP协议)
  • 套接字(Socket)和服务器套接字(ServerSocket)用来实现TCP协议
    == 客户端(发起请求) => Socket【发送数据,使用传输层中的TCP协议】=> 服务器端(一直等待状态)
  • 数据报(DatagramPacket)和数据报套接字(DatagramSocket)用来实现UDP协议
  • 统一资源定位器(URL)用来访问Internet

代码部分:

InetAdressDemo.java

/**
 * 演示Internet地址访问
 * tips:alt + / 自动提示
 * @author soft01
 */
public class InetAddressDemo {

	public static void main(String[] args) throws Exception {
		InetAddress byName = InetAddress.getByName("www.tmooc.cn");
//		System.out.println(byName); //获取www.tmooc.cn的IP
		InetAddress[] names = InetAddress.getAllByName("www.tmooc.cn"); //获取www.tmooc.cn中all的IP
		//for循环
//		for (int i = 0; i < names.length; i++) {
//			System.out.println(names[i]); //tips:联网才能访问更多!
//		}
		//增强for循环
//		for (InetAddress name : names) { //"name" 见名知意
//			System.out.println(name);
//		}
		
		//获取本机IP地址
//		InetAddress localhost = InetAddress.getLocalHost();
//		System.out.println("本机IP地址:" + localhost); 
		
		//获取回环地址【localhost:127.0.0.1 本地IP地址】
//		InetAddress loop = InetAddress.getLoopbackAddress();
//		System.out.println("回环地址:"  + loop);
		
		//根据指定的IP地址获取
		InetAddress byAddress = InetAddress.getByAddress(new byte[] {-10, -20, -1, 0}); //数值范围:-128~127
		System.out.println("指定的IP地址:"  +  byAddress); //指定的IP地址:/246.236.255.0
	}

}

不同系统下,获取本地IP地址相关信息访问:
Windows下DOS打开输入ipconfig Linux下打开终端输入ifconfig

UrlCoderDemo.java

/**
 * 演示字符集编码和解码
 * @author soft01
 */
public class UrlCoderDemo {

	public static void main(String[] args) throws Exception {
		String url1 = "清华大学";
		//对字符集进行编码
		String encoder = URLEncoder.encode(url1, "UTF-8");
		System.out.println(encoder); //%E6%B8%85%E5%8D%8E%E5%A4%A7%E5%AD%A6
		//对字符集进行解码
		String url2 = "%E6%B8%85%E5%8D%8E%E5%A4%A7%E5%AD%A6";
		//Light背景下黑色的删除线的意思是不建议使用
		String decoder = URLDecoder.decode(url2); //若输出乱码可修改为:.decode(url2, "UTF-8"); tips:修改后无删除线
		System.out.println(decoder); //清华大学
	}
	
}

UrlDemo.java

/**
 * 演示URL使用
 * tips:类名冲突
 * @author soft01
 */
public class UrlDemo {

	public static void main(String[] args) throws Exception {
		//创建URL对象【url:统一资源定位符/器】
		URL url = new URL("http://doc.canglaoshi.org");
		//打开链接
		URLConnection connection = url.openConnection();
//		System.out.println(connection); //sun.net.www.protocol.http.HttpURLConnection:http://www.tmooc.cn/
		//获取文本类型
		String type = connection.getContentType();
		System.out.println(type); //text/html
		//获取文本的长度【int类型】
		int length1 = connection.getContentLength();
		System.out.println("Content-LenghInt:" + length1); //-1
		//获取文本的长度【long类型】
		long length2 = connection.getContentLengthLong();
		System.out.println("Content-LenghInt:" + length2); //-1
		//tips:-1表示没有访问到路径【网络配置可能受限】
		//获取日期【从1970年1月1号到现在的毫秒数】
		System.out.println("Date:" + connection.getDate());
		
		//判断连接是否为空
		if (connection != null) {
			//如何去读取里面的信息?
			//创建输入流的对象
			InputStream is = connection.getInputStream();
			//创建缓冲区,将输入的对象放入缓冲区当中
			BufferedInputStream bis = new BufferedInputStream(is);
			//创建输出流的对象
			FileOutputStream fos = new FileOutputStream("1.html"); //查看Properties下Path,1.html位置是位于day01下
			//创建缓冲区,将输出的对象放入缓冲区当中
			BufferedOutputStream bos = new BufferedOutputStream(fos);
			//read() 是按字节进行读取,读取到最后一位时是 -1
			int c;
			while ((c = bis.read()) != -1) {
				System.out.println(c);
				//java.net.UnkownHostException:表示找不到路径地址报出异常
				//将字符写入到输出流对象
				bos.write(c);
				//冲刷
				bos.flush();
			};
			System.out.println("输出成功");
			//关流
			is.close();
		}
	}
	
}

UDP和TCP

  • UDP(User Datagram Protocol)即用户数据协议,是一个面向无连接的协议,能够提供多路复用和差错检测的功能,但是不能去保证数据的正确性和重复出现,UDP协议对于简单的请求是有用的,因为UDP协议不需要像TCP协议一样在去建立连接的时候需要花费时间,传输速率是比较高
  • TCP(Transmission Control Protocol)即传输控制协议,是一个面向连接的协议,能够提供双向【指客户端和服务端,客户端发起请求到服务器端,服务器端作出响应返给客户端】,可靠,有流量控制的字节流服务
    字节流服务:在一个TCP连接里面,以字节的形式去进行传输
  • TCP协议的7个特征:
  • (1)面向连接:发送数据的一方必须要请求另一方的同意,才可以去建立连接,然后通过这一连接去发送数据
  • (2)点对点通信:原地址和目的地址之间可以通信,其他方式均不可,例如:广播/组播
  • (3)完全可靠性:确保通过一个连接发送的数据,能够正确的抵达另一方,而且不会发生数据的紊乱和丢失
  • (4)全双公通信:再去建立连接的同时,能够保证既可以输入数据,也可以输出数据,并且不会影响到其他的应用程序
  • (5)流接口:TCP提供了一个流接口,保证数据的输入和输出,一个应用利用它可以连续发送数据
  • (6)可靠的连接建立:TCP要求两个应用创建一个连接时,两端必须遵从新的连接,前一次所用的重复的连接是非法的
  • (7)友好的连接终止【断网或网络访问不稳定下】:一个应用程序打开一个连接发送任意量的数据,然后请求终止,TCP能够确保在关闭连接之前,传递的数据能发送给目的地址

代码部分:

Server.java

/**
 * 演示客户端连接(服务器端)
 * @author soft01
 */
public class Server {

	public static void main(String[] args) throws IOException {
		//创建一个ServerSocket,用于监听客户端Socket的请求
		//端口号:8888【1~1023是默认的端口号[PID]、1024~65535是可用的】
		//1.申请端口
		//2.接收该端口所有客户端的连接
		//所有的外部应用程序都会有一个端口号
		System.out.println("正在启动服务端......");
		ServerSocket ss = new ServerSocket(8888); //客户端访问的端口号
		System.out.println("服务端启动完毕");
		//开始监听服务器端口,accept()是阻塞方法,等待客户端连接,如果没有连接,会一直阻塞
//		Socket socket = ss.accept();
//		System.out.println("客户端已经连接");
		//注:启动一个服务器端多个客户端可以连接
		int i = 1;
		while (true) {
			Socket socket = ss.accept();
			System.out.println("第"  + i + "客户端已经连接"); //多次运行客户端使得i累加
			i++;
		}
		/*
		 * Exception in thread "main" java.net.BindException:Address already in use: JVM_Bind
		 *   表示绑定异常,在服务器运行的情况下,再运行服务器,使得端口号被占用
		 */
	}
	
}

Client.java

import java.net.Socket;
/**
 * 演示服务器端连接(客户端)
 * @author soft01
 */
public class Client {
	
	public static void main(String[] args) throws Exception {
		//服务器端的地址信息,第一个参数是本地的IP地址,第二个是端口号
		System.out.println("正在连接服务端.......");
		Socket socket = new Socket("127.0.0.1", 8888);
		System.out.println("已经连接到服务端!");
		/*
		 * Exception in thread "main" java.net.ConnectException: Connection refused: connect
		 *   表示连接异常,在服务器终止的情况下,客户端去访问服务器,就会报出上述错误
		 */
	}

}

注意:程序运行时,先连接客户端再连接服务器端

练习:

Server1.java

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server1 {

	public static void main(String[] args) throws IOException {
		ServerSocket ss = new ServerSocket(6666);
		Socket socket = ss.accept();
		//当客户端发起请求时才会响应
		//获取服务器端IP地址
		System.out.println("服务器LocalAddress:" + socket.getLocalAddress()); //服务器LocalAddress:/127.0.0.1
		//获取服务器端端口号
		System.out.println("服务器LocalPort:" + socket.getLocalPort()); //服务器LocalPort:6666
		//获取客户端地址
		System.out.println("客户端InetAddress:" + socket.getInetAddress()); //客户端InetAddress:/127.0.0.1
		//获取客户端端口号
		System.out.println("客户端Port:" + socket.getPort()); //客户端Port:41704 随机
	}
	
}

Clent1.java

public class Client1 {

	public static void main(String[] args) throws Exception {
		Socket socket = new Socket("127.0.0.1", 6666);
		//获取服务器端IP地址
		System.out.println("服务器LocalAddress:" + socket.getLocalAddress()); //服务器LocalAddress:/127.0.0.1
		//获取服务器端端口号
		System.out.println("服务器LocalPort:" + socket.getLocalPort()); //服务器LocalPort:41704 随机
		//获取客户端地址
		System.out.println("客户端InetAddress:" + socket.getInetAddress()); //客户端InetAddress:/127.0.0.1
		//获取客户端端口号
		System.out.println("客户端Port:" + socket.getPort()); //客户端Port:6666
	}

}