一、概述

记录时间 [2024-11-30]

本文讲述如何实现本机和服务器之间的 UDP 通信,以及防火墙的相关知识,总结了一些常用的防火墙操作命令。

在实现 UDP 通信过程中,涉及到通信端口,需要在防火墙处放行端口。

  • 放行端口,看标题三;
  • UDP 通信,看标题四;
  • 常用的防火墙命令,看标题五。


二、认识防火墙

防火墙用于监控进出网络的数据流量,阻止未经授权的访问和恶意攻击,确保网络的安全性和完整性

防火墙可以基于预定义的规则集,允许或阻止特定类型的流量通过。

防火墙可以配置允许或拒绝特定的端口、IP 地址、应用程序或数据包类型的流量。正确配置和管理防火墙是确保网络安全的重要步骤,需要根据组织的安全策略和需求进行定期审查和更新。

阿里云服务器具备两道防火墙,一道在 Linux 操作系统中配置,一道在阿里云安全组中配置。

Linux 操作系统中自带一道防火墙,阿里云安全组是阿里云提供的一种虚拟防火墙服务。它们都是软件层面的防火墙。

重点!有关网络通信的部分,都与这两道防火墙有关系!!



三、操作防火墙

需要同时开启阿里云安全组和本地防火墙。

1. 阿里云安全组

阿里云安全组的设置通过阿里云提供的控制台操作。

控制台里面有一个设置防火墙的选项,点击添加规则,就可以进行操作。

以我们下面要实现的 UDP 通信为例,开放一个 UDP 协议的端口。

开放阿里云安全组:

  • 端口协议:UDP;
  • 端口号:6699(自定义);
  • 来源 IP:0.0.0.0/0 代表所有IPv4 地址,想要限制 IP 来源可填写单个 IP。

在这里插入图片描述


2. 本地防火墙

在 Linux 中,本地防火墙有很多种操作方式,文章中采用的是 firewalld 防火墙工具。

同样,以我们下面要实现的 UDP 通信为例,开放一个 UDP 协议的端口。


启动防火墙

# 检查防火墙的状态
# Active: active (running) 表示开启了,正在运行中
systemctl status firewalld

# 启动防火墙
systemctl start firewalld

# 关闭防火墙
systemctl stop firewalld

开放端口

  • tcp 和 udp 是两套不同的协议,各自有 1~65535 的端口。
  • --permanent 表示永久生效,没有此参数,重启后该规则失效。
# 检查操作系统中所有开放的端口
firewall-cmd --zone=public --list-ports

# 查看指定端口是否开放
firewall-cmd --zone=public --query-port=6699/udp

# 开放端口 6699/udp
# --permanent 表示永久生效,没有此参数重启后失效
firewall-cmd --zone=public --add-port=6699/udp --permanent

更新防火墙的设置

# 更新防火墙的设置,使上面的修改生效
firewall-cmd --reload

检查端口开放情况

# 检查操作系统中所有开放的端口
firewall-cmd --zone=public --list-ports


四、UDP 通信

UDP 通信中有发送端和接收端,发送端根据接收端的 IP 和端口给接收端发消息。

发送端和接收端不需要建立连接。

这里我们用本机模拟发送端,服务器模拟接收端,用本机给服务器发消息。

接收端(服务器)的 公网 IP 详见阿里云控制台,端口自定义,文章中使用的端口是 6699。


1. 开发环境

本机:Windows 11,JDK 1.8,参考文章 - Java 环境配置

阿里云服务器:Linux CentOS 7,JDK 1.8,参考文章 - JDK 安装

检查 Java 环境:java -version

通过 Xshell 和 Xftp 连接远程服务器,参考文章 - 远程连接工具的使用


2. 本机发送端

使用 IDEA 编写 Java 程序,实现 UDP 通信中的发送端。

获取服务器的地址:

  • IP :122.11.2.23(不是真的,根据实际来)
  • Port :6699

编写代码:

// 发送端
public class UdpSendDemo01 {
    public static void main(String[] args) throws Exception {

        // 1. 建立一个 socket, 开放端口
        DatagramSocket socket = new DatagramSocket();

        // 2. 准备一个数据包
        String msg = "这是一个数据包";
        InetAddress inetAddress = InetAddress.getByName("122.11.2.23");

        // 数据包, 数据的长度起始, 结束, 对方ip, 对方端口
        DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, inetAddress, 6699);

        // 3. 发送数据包
        socket.send(packet);
        System.out.println("Message sent to the server.");

        // 4. 关闭资源
        socket.close();
    }
}

3. 服务器接收端

使用 Xshell 连接远程服务器,在 Xshell 中进行操作,实现 UDP 通信中接收端。

  • 创建 Java 文件
# 创建并编辑 Java 文件
vi UdpReceiveDemo01.java

# 进入文件后,按下 i 键,编辑文件

  • UdpReceiveDemo01.java 文件中的内容
  • 重点检查开放的端口,本机是根据这个端口发消息的。
import java.net.*;
public class UdpReceiveDemo01 {
    public static void main(String[] args) throws Exception {
        // 1. 开放端口
        DatagramSocket socket = new DatagramSocket(6699);
        
        // 2. 接收数据包
        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
        
        // 阻塞接收
        socket.receive(packet);
        
        // 3. 查看数据包
        // 发送端的 IP
        System.out.println(packet.getAddress().getHostAddress());
        // 数据包的内容
        System.out.println(new String(packet.getData(), 0, packet.getLength()));
        
        // 4. 关闭资源
        socket.close();
    }
}

  • 保存文件
# 写完后,按下 ESC 键
:wq		# 保存文件

:q!		# 不保存
:q		# 不修改不保存

  • 检查文件
  • 编译文件,没有报错就是通过了编译,报错了就按照 Java 程序的规范,检查文件内容有没有写错。
# 打印出这个文件,方便检查
cat UdpReceiveDemo01.java

# 编译文件,没有报错就是通过了编译
javac UdpReceiveDemo01.java

4. 测试

先检查本机网络,确保本机正常上网。

检查上面两道防火墙,确保测试的端口正常放行。

先运行接收端(服务器):

# 运行 Java 程序
java UdpReceiveDemo01

再运行发送端(本机):IDEA 一键运行。

观察 Xshell 中的结果:

本机的 IP
这是一个数据包


五、常用的防火墙命令

整理了一些防火墙命令,经常会用到。用的是 firewalld 防火墙工具。

1. 防火墙操作命令

# 检查防火墙的状态(详细的)
systemctl status firewalld

# 检查防火墙的状态(简洁的)
firewall-cmd --state

# 查看防火墙的所有信息
firewall-cmd --list-all

# 启动防火墙(立即启动,但重启不生效)
systemctl start firewalld

# 设置防火墙开机自启动(不会立即启动)
systemctl enable firewalld

# 设置防火墙开机自启动,并立刻启动(立即启动)
systemctl enable firewalld --now

# 关闭防火墙(立即关闭,但重启不生效)
systemctl stop firewalld

# 停用防火墙,重启生效(不会立即关闭)
systemctl disable firewalld

# 重新加载防火墙规则
firewall-cmd --reload

# 重启防火墙服务
systemctl restart firewalld.service

2. 端口操作命令

注意点:开放或关闭端口后,需要重新加载防火墙规则才能生效。也可以重启防火墙服务。

# 检查操作系统中所有开放的端口
firewall-cmd --zone=public --list-ports

# 查看指定端口是否开放
firewall-cmd --zone=public --query-port=6699/udp
	--query-port=端口号/协议

# 开放端口
firewall-cmd --zone=public --add-port=6699/udp --permanent
	--permanent		# 表示永久生效,没有此参数重启后失效
	--add-port=端口号/协议

# 关闭端口
firewall-cmd --zone=public --remove-port=80/tcp --permanent
	--remove-port=端口号/协议

# 批量开放端口
firewall-cmd --zone=public --add-port=40000-45000/tcp --permanent
	--add-port=40000-45000/tcp		# 打开从 40000 到 45000 之间的所有 tcp 端口

# 批量关闭端口
firewall-cmd --zone=public --remove-port=40000-45000/tcp --permanent
	--remove-port=40000-45000/tcp	# 关闭从 40000 到 45000 之间的所有 tcp 端口

# 重新加载防火墙规则
firewall-cmd --reload

# 检查操作系统中使用的端口
netstat -tuln
	-t		# 显示 TCP 协议的连接
	-u		# 显示 UDP 协议的连接
	-l		# 显示监听状态的连接
	-n		# 以数字形式显示地址和端口号

# 检查端口是否被占用
netstat -tuln | grep 8080
	grep 端口号


参考资料

参考文章 - Windows 11 Java 环境配置:https://blog.csdn.net/Sareur_1879/article/details/137963848

参考文章 - Linux CentOS 7 JDK 安装:https://blog.csdn.net/Sareur_1879/article/details/138228126

参考文章 - 远程连接工具的使用:https://blog.csdn.net/Sareur_1879/article/details/137999601

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐