网络编程

三要素

  • IP

    • 127.0.0.1 (永远表示本机)
  • 端口号

    • 取值范围为0~65535, 其中0~1023之间的端口号已用于一些知名的网络服务或应用
  • 协议

    • UDP: 面向无连接, 速度快, 大小限制一次最多发送64K, 数据不安全, 易丢失
    • TCP: 面向连接, 速度慢, 没有大小限制, 数据安全

InetAddress类

  • static InetAddress getByName(String host) : 确定主机名称的IP地址. 主机名称可以是机器名称, 也可以是IP地址获取此IP地址的主机名

  • String getHostName() : 获取此IP地址的主机名

  • String getHostAddress() : 返回文本显示中的IP地址字符串

UDP通信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 发送端 */

// 1.创建DatagramSocket对象
// 空参: 所有可用的端口中随机一个进行使用
// 有参: 指定端口号进行绑定
DatagramSocket socket = new DatagramSocket();

// 2.打包数据
String str = "hello";
byte[] bytes = str.getBytes(); // 发送的数据
InetAddress address = InetAddress.getByName("127.0.0.1"); // 发送到的ip地址
int port = 10086; // 发送到的端口号
DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);

// 3.发送数据
socket.send(dp);

// 4. 释放资源
socket.close();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 接收端 */

// 1.创建DatagramSocket对象
// 接收的时候一定要绑定端口, 且该端口号与接收的端口号一致
DatagramSocket socket = new DatagramSocket(10086);

// 2.接收数据包
byte[] bytes = new byte[1024]; // 接收的容器, 容量要大于等于所要接收的数据长度
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
socket.receive(dp); // 该方法是阻塞的, 当程序运行到这时会死等, 直到接收到数据才能继续往下运行

// 3.解析数据包
byte[] data = dp.getData(); // 获取数据
int len = dp.getLength(); // 获取数据长度
InetAddress address = dp.getAddress(); // 获取发送端的ip
int port = dp.getPort(); // 获取发送端发送的端口号

// 4.释放资源
socket.close();
  • 三种通信方式

    • 单播: 上述代码为单播

    • 组播: 224.0.0.0 ~ 239.255.255.255, 其中224.0.0.0 ~ 224.0.0.255为预留的组播地址

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      /* 发送端 */
      // 第一步为创建MulticastSocket对象
      MulticastSocket ms = new MulticastSocket();


      /* 接收端 */
      // 第一步为创建MulticastSocket对象
      MulticastSocket ms = new MulticastSocket();

      // 在接收数据包前要将本机添加到发送端发送的组播地址中
      InetAddress address = InetAddress.getByName("224.0.0.1");
      ms.joinGroup(address);
    • 广播: 255.255.255.255

TCP通信

  • 通信之前要保证连接已经建立

  • 通过socket产生IO流来进行网络通信

    image-20250118234636886

1
2
3
4
5
6
7
8
9
10
11
12
/* 客户端 */
// 1.创建Socket对象
// 在创建对象的同时会连接服务端, 如果连接不上, 代码会报错
Socket socket = new Socket("127.0.0.1", 10000);

// 2.从连接通道中获取输出流
OutputStream os = socket.getOutputStream();
os.write("hello".getBytes()); // 写出数据

// 3.释放资源
os.close();
socket.close();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 服务端 */
// 1.创建ServerSocket对象
ServerSocket ss = new ServerSocket(10000);

// 2.监听客户端连接
Socket socket = ss.accept();

// 3.从连接通道中获取输入流读取数据
InputStream is = socket.getInputStream(); // 字节流, 不能接收中文
InputStreamReader isr = new InputStreamReader(is); // 转换为字符流
BufferedReader br = new BufferedReader(isr); // 转换为缓冲流, 提高效率
// BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
int b;
while((b = br.read()) != -1) {
sout((char) b);
}

// 4.释放资源
socket.close();
ss.close();