网络通信:两台设备之间通过网络实现数据的传输(将数据从一台设备传递到另一台设备)

Java.net包提供一系列的接口和方法供程序员使用,完成网络通信。

网络:两台或多台设备通过一定的物理设备连接起来构成了网络。

ip地址用来表示每一台计算机;端口号用来表示计算机上的某个特定的网络服务。

所以电脑浏览器通过访问IP+端口进而访问不同的网站服务。

Java.net包下的InetAddress类提供了一系列操作IP的方法

首先,介绍一下InetAddress类中的方法:

        InetAddress是Java对Ip地址的封装

        InetAddress类中的方法都是static,因此可以通过类名.方法名进而调用。

// getLocalHost():得到当地的主机对象
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost); // DESKTOP-HF5FSPA/192.168.56.1
    // getByName():根据主机名获取InetAddress对象
InetAddress host1 = InetAddress.getByName("DESKTOP-HF5FSPA");
System.out.println("host1=" + host1);
    // getByName():根据域名获取InetAddress对象
InetAddress host2 = InetAddress.getByName("www.baidu.com");
System.out.println("host2=" + host2);

    // getHostAddress():根据相应的InetAddress对象获得相应的地址
String hostAddress = host2.getHostAddress();
System.out.println("host2对应的ip地址" + hostAddress);
    // getHostName():根据相应的InetAddress对象获得相应的主机名或域名
String hostName = host2.getHostName();
System.out.println("host2对应的主机名" + hostName);

Socket:套接字。

        网络通信其实就是Socket之间的通信。可以把Socket理解为“数据通道的插头”

通信两端都存在Socket,是两台机器间的通信端点。

Socket允许把网络连接当成一个流,数据在两个Socket之间通过IO流进行传输。

即:客户端(Socket)-----------  服务端(Socket)

调用socket.getInputStream()、socket.OutputStream()向数据通道出入或读取数据,进行通讯。

// 使用Socket完成字节流的传递

// 服务端代码
// 对于服务器来说,接收客户端传入数据通道的数据并回复“收到”
    // 开启9999端口监听(要求本机没有其他服务监听9999端口)
    // ServerSocket可以通过accept()返回多个socket【多个客户端连接服务器的并发操作】
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服务器9999端口开启监听....");
Socket socket = serverSocket.accept();
    // 通过socket.getInputStream()读取客户端写入到数据通道的实际长度,显示内容
InputStream is = socket.getInputStream();
    // 通过IO流读取数据
byte[] buf = new byte[1024];
int len = 0;
while ((len = is.read(buf)) != -1) {
    System.out.println(new String(buf, 0, len)); // 显示在控制台
}
    // 利用OutputStream将数据写入数据通道
OutputStream os = socket.getOutputStream();
os.write("收到!!".getBytes(StandardCharsets.UTF_8));
    // 设置结束标记,表示传送数据结束
socket.shutdownOutput();
    // 关闭io流,释放资源
is.close();
os.close();
socket.close();
serverSocket.close();
System.out.println("关闭服务器");

// 客户端代码
    // 连接本机的9999端口,开启数据通道
Socket socket = new Socket(InetAdress.getLocalHost(), 9999);
    // 连接上后,通过socket.getOutputStream()传输数据
OutputStream os = socket.getOutputStream();
os.write("hello, server".getBytes());
    // 发送完成后,应该加一个结束标记,表示数据输出结束。否则接收会不清楚什么时候结束传送
socket.shutdownOutput();
    // 利用getInputStream()接收服务器写入数据通道的数据
InputStream is = socket.getInputStream();
byte[] buf = new byte[1024];
int readLen = 0;
while ((readLen = is.read(buf)) != -1) {
    System.out.println(new String(buf, 0, readLen));
}
    // 关闭输出流
is.close();
os.close();
    // 释放资源
socket.close();
System.out.println("关闭客户端");
// 使用Socket完成字符流的传递

    // 对于服务器来说,接收客户端传过来的数据,并回复 
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服务器 9999端口正在监听....");
Socket socket = serverSocket.accept();
InputStream is = socket.getInputStream();
    // 利用转换流将字节流转为字符流
    // 从数据通道中读数据
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String str = br.readLine();
System.out.println(str);
    // 向数据通道中写数据
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write("hello,Client 字符流");
bw.newLine(); // 传送结束标记,表示传送数据结束
bw.flush(); // 手动刷新
    // 关闭io流,释放资源
br.close();
socket.close();
System.out.println("服务端退出.....");

    // 对于客户端来说,向服务端传递数据
Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
OutputStream os = socket.getOutputStream();
    // 利用转换流将字节流转为字符流
    // 向数据通道中写数据
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write("hello, server 字符流");
    // 设置字符结束标志
bw.newLine(); // 使用newLine()表示结束时,要求对方必须使用readLine()进行读取
bw.flush(); // 使用的字符流,必须手动刷新,否则数据就不会写入数据通道
    // 从数据通道中读数据
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String str = br.readLine();
System.out.println(str);
    // 关闭io流,是否资源
bw.close();
socket.close();
System.out.println("客户端退出.....");