java学习笔记(二十一)- 网络通信

一、网络通信

1. 概念

  • 将数据通过网络从一台设备传输到另一台设备

二、网络

1. 概念

  • 两台设备通过一定物理设备连接起来构成了网络

2. 分类

  • 根据网络覆盖范围不同进行分类

2.1 局域网

  • 覆盖范围最小,仅覆盖一个教室或者一个机房

2.2 城域网

  • 覆盖范围较大,可以覆盖一个城市

2.3 广域网

  • 覆盖范围最大,可以覆盖全国甚至全球,万维网是广域网的代表

三、IP地址

1. 概念

  • 用于唯一标识网络中的每台计算机
  • 表示形式:点分十进制 xx.xx.xx.xx
  • 每一个十进制数的范围:0~255
  • 查看IP地址:dos控制台 输入ipconfig

2. 组成

  • ip地址的组成=网络地址 + 主机地址,如:192.168.16.69

3. IPV4

  • 4个字节(32位)表示,一个字节的范围是0~255

3.1 分类

  • 特殊的:172.0.0.1 表示本机地址
类型 范围
A 0.0.0.0 到 127.255.255.255
B 128.0.0.0 到 191.255.255.255
C 192.0.0.0 到 223.255.255.255
D 224.0.0.0 到 239.255.255.255
E 240.0.0.0 到 247.255.255.255

四、域名

  • www.baidu.com 将ip地址映射成域名

五、端口

1. 概念

  • 用于标识计算机上的某个特定的网络程序

2. 表示形式

  • 以整数形式,端口范围0~65535[2个字节表示端口0~2^16-1]
  • 0~1024已经被占用,如ssh 22,ftp 21,smtp 25,http 80
  • 常见的网络程序端口号:
    1. tomcat:8080
    2. mysql:3306
    3. oracle:1521
    4. sqlserver:1433

3.图示

  • 在网络开发中因避免使用1~1024范围中的端口

六、网络通信协议

1. TCP/IP协议

  • 英文全称:Transmission Control Protocol/Internet Protocol

  • 中文:传输控制协议/因特网互联协议,又叫网络通讯协议

  • 是Internet最基本的协议,国际互联网的基础

  • 由网络层的IP协议和传输层的TCP协议组成

2. TCP 传输控制协议

  • 使用TCP协议前,须先建立TCP连接,形成传输数据通道
  • 传输前,采用”三次握手”方式,是可靠的
  • TCP协议进行通信的两个应用进程:客户端、服务端
  • 在连接中可进行大数据量的传输
  • 传输完毕,需释放已建立的连接,效率低

3. UDP 用户数据协议

  • 将数据、源、目的封装成数据包,不需要建立连接
  • 每个数据报的大小限制在64K内,不适合传输大量数据
  • 因无需连接,故是不可靠的
  • 发送数据结束时无需释放资源(因为不是面向连接的),速度快

七、InetAddress 类

1. 方法

1
2
3
4
getLockHost//获取本机InetAddress对象
getByName//根据指定主机名/域名获取ip地址对象
getHostName//获取InetAddress对象主机名
getHostAddress//获取InetAddress对象的地址

八、Socket 套接字

1. 基本介绍

  • 套接字(Socket)开发网络应用程序被广泛采用,以至于成为事实上的标准
  • 通信的两端都要有Socket,是两台机器间通信的端点
  • 网络通信其实就是Socket间的通信
  • Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输
  • 一般主动发起通信的应用程序属客户端,等待通信请求的为服务端

2. 用法

  • 根据用户输入在服务端下载指定音乐文件,如果不是则返回下载默认音乐文件

2.1 Server端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/**
* @author 一个凡人
* @version 1.0
* 服务端
*/
public class Homework03Server {
public static void main(String[] args) throws IOException {
//1. 创建端口等待连接
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服务端等待连接....");
//2. 创建Socket对象 如果被连接就返回 Socket对象
Socket socket = serverSocket.accept();
//3. 接收客户端的内容
// 这里采用字符流的方式接收
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = br.readLine();
//4. 如果客户端发送的内容是 坦克大战背景音乐 就发送tk.mp3给客户端
// 否则返回默认音乐 7301.mp3
String filePath;//定义文件路径
if ("坦克大战背景".equals(line)) {
filePath = "j:\\tk.mp3";
} else {
filePath = "j:\\7301.mp3";
}
// 读取文件
// 给客户端发送音乐 采用字节流
OutputStream outputStream = socket.getOutputStream();
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));
byte[] buf = new byte[1024];
int len = 0;
//一边读一边发送
while((len = bis.read(buf)) != -1) {
outputStream.write(buf,0,len);
}
//设置结束标记
socket.shutdownOutput();
//关闭资源
socket.close();
outputStream.close();
bis.close();
br.close();
serverSocket.close();
System.out.println("服务端退出...");
}
}

2.2 Client端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;


/**
* @author 一个凡人
* @version 1.0
* 客户端
*/
public class Homework03Client {
public static void main(String[] args) throws IOException {
//1. 连接端口
Socket socket = new Socket(InetAddress.getLocalHost(), 9999);

//2. 给服务端发送需要下载的音乐名 采用Scanner
Scanner scanner = new Scanner(System.in);
System.out.println("请输入需要下载的音乐名:");
String musicName = scanner.next();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bw.write(musicName);
bw.flush();//刷新
socket.shutdownOutput();//结束标记

//3. 接收服务端发送的文件 并保存到 e:\\
String destPath = "e:\\" + musicName + ".mp3";
BufferedOutputStream bos =
new BufferedOutputStream(new FileOutputStream(destPath));
InputStream inputStream = socket.getInputStream();
byte[] data = new byte[1024];
int len = 0;
//循环读取
while((len = inputStream.read(data)) != -1) {
bos.write(data,0,len);
bos.flush();
}
//关闭资源
bos.close();
inputStream.close();
bw.close();
socket.close();
System.out.println("客户端退出....");
}
}

九、netstat 指令

  • dos控制台下执行 win+r说明:

  • netstat -an可以查看当前主机网络情况,包括端口监听情况和网络连接情况

  • netstat -an | more 可以分页显示
    • Listening表示某个端口在监听
    • 如果有一个外部程序(客户端)连接到该端口,就会显示一条连接信息.
    • 可以输入ctrl +c退出指令

十、UDP 网络通信编程

1. 使用

  • 使用UDP进行发送消息

1.1 发送端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import java.io.IOException;
import java.net.*;

/**
* @author 一个凡人
* @version 1.0
* 发送端 ---->也可以接收数据
*/
public class UDPSendB {
public static void main(String[] args) throws IOException {
//1. 创建 DatagramSocket对象 接收和发送数据
DatagramSocket socket = new DatagramSocket(9998);

//2. 将需要发送的数据,封装到 DatagramPacket对象
byte[] data = "hello,明天去吃火锅...".getBytes();
// 说明:封装的DatagramPacket 对象data 内容字节数组, data.length, 主机(ip), 端口
DatagramPacket packet =
new DatagramPacket(data, 0, data.length, InetAddress.getByName("192.168.42.96"), 9999);
socket.send(packet);

//3. 接收
byte[] buf = new byte[1024];
DatagramPacket packet1 = new DatagramPacket(buf, buf.length);
socket.receive(packet1);

//拆包显示内容
int length = packet1.getLength();
byte[] data1 = packet1.getData();
String s = new String(data1, 0, length);
System.out.println(s);

//关闭资源
socket.close();
System.out.println("B端退出...");
}
}

1.2 接收端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;


/**
* @author 一个凡人
* @version 1.0
* 接收端
*/
public class UDPReceiveA {
public static void main(String[] args) throws IOException {
//1. 创建一个 DatagramSocket 对象 准备在9999接收数据
DatagramSocket socket = new DatagramSocket(9999);
//2. 创建一个 DatagramPacket 对象 准备接收数据
// UDP协议一个数据包最大64k
byte[] buf = new byte[64 * 1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
//3. 调用方法 将通过网络传输的 DatagramPacket对象
// 注意:当有数据包发送到9999端口时,就会接收到数据
// 如果没有数据包发送,就会阻塞
System.out.println("接收端A 等待接收数据...");
socket.receive(packet);

//4. 把packet拆包 取出数据并显示
int length = packet.getLength();//实际接收到的数据字节长度
byte[] data = packet.getData();//接收到的数据
String s = new String(data, 0, length);
System.out.println(s);

//5. 发送“好的,明天见”
byte[] data1 = "好的,明天见...".getBytes();
DatagramPacket packet1 =
new DatagramPacket(data1, 0, data1.length, InetAddress.getByName("192.168.42.96"), 9998);

socket.send(packet1);

//关闭资源
socket.close();
System.out.println("A端退出...");
}
}