
# 通过独享型ELB的全端口监听支持UDP大包分片传输
#### 应用场景
在使用客户端发送UDP数据包进行通信时，如果数据包较大，可能会被IP层分片。当这些分片的数据包通过ELB时，由于UDP监听器不支持大包分片，后端服务器无法接收到完整的分片报文，导致访问异常。面对这种情况，如何确保数据包能够完整地被后端服务器接收，避免访问异常的发生？本实践文档提供了一种解决方案，通过配置ELB的**全端口监听** ，确保UDP分片数据包能够被分配到**同一台后端服务器**后进行正确重组，从而避免访问异常。
#### 什么是IP分片
IP分片（IP Fragmentation）是网络通信中用于处理大数据包传输的一种技术。当数据包的大小超过网络链路的最大传输单元（MTU）时，路由器或发送端会将原始数据包分割成多个较小的片段（分片），以便在网络上传输。接收端收到这些分片后，会重新组装（Reassembly）还原为原始数据包。
#### 约束与限制
- 当前ELB仅支持入方向IP分片的传输，暂不支持从服务端发送的IP分片报文传输到客户端。
- ELB根据UDP分片报文中相同的源IP地址将分片报文转发到相同的后端服务器，后端服务器组的分配策略类型请选择"**源IP算法**"。
 
#### 准备工作
- 已创建独享型ELB实例，具体操作请参考[购买独享型负载均衡器](https://support.huaweicloud.com/usermanual-elb/elb_lb_000006.html)。
- 创建两台ECS，ECS与已创建的ELB实例属于同一个VPC，更多详细设置请参考[自定义购买ECS](https://support.huaweicloud.com/usermanual-ecs/ecs_03_7002.html)。
  一台ECS_client用作客户端发送请求，另一台ECS_server用作部署UDP后端应用服务的后端服务器。
  
 
#### 步骤一：创建UDP监听器并设置1\~65535端口监听
1. 进入[弹性负载均衡列表页面](https://console.huaweicloud.com/vpc/?locale=zh-cn#/elb/list)。
2. 在弹性负载均衡列表页面，单击需要添加监听器的负载均衡名称。
3. 切换到"监听器"页签，单击"添加监听器"，配置UDP监听器并配置1\~65535端口的全端口监听。
   - 监听端口：全端口监听。
   
   - 起始端口：1，结束端口：65535。
   
   
   图1添加UDP监听器并设置1\~65535端口的全端口监听   
   ![](https://support.huaweicloud.com/bestpractice-elb/zh-cn_image_0000002509518759.png "点击放大") 
4. 其余配置保持默认，单击"下一步：配置后端分配策略"。
 
#### 步骤二：创建基于源IP算法的后端服务器组
1. 在配置后端分配策略页面，选择"新创建"后端服务器组。
2. 分配策略类型选择"**源IP算法** "，并开启"**全端口转发** "，其余配置保持默认。
   图2新创建UDP协议的后端服务器组   
   ![](https://support.huaweicloud.com/bestpractice-elb/zh-cn_image_0000002477480620.png "点击放大") 
3. 单击"下一步：添加后端服务器"，添加准备工作中已经创建的ECS_server作为后端服务器。
4. 单击"下一步：确认配置"，确认无误后，单击"提交"。
 
#### 步骤三：验证UDP大包传输生效
1. 远程登录后端服务器ECS_server。 弹性云服务器有多种登录方法，具体请参见[登录弹性云服务器](https://support.huaweicloud.com/ecs_faq/ecs_faq_0632.html)。
   
2. 在后端服务器中，新建目录Test。
   ```
   mkdir Test
   ```
   
3. 在Test目录下，新建一个send.py，用于向ELB发送UDP大包分片报文。
   1. 新建send.py文件。
      ```
      python send.py
      ```
      
   
   2. 按**i** 键进入编辑模式。
      单击查看本示例代码参考
      - send.py文件脚本，用于向ELB发送UDP大包分片报文。
        ```
        import socket
        target_ip = "192.168.1.100"   # 指定目标IP为ELB的对外服务的IP
        target_port = 12345           # 指定目标端口为ELB的监听端口
        udp_data = b"A" * 2000   # 构造超过MTU的UDP数据，包含2000字字符A的二进制数据
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)   # 创建用于UDP通信的Socket对象
        sock.sendto(udp_data,(target_ip,target_port))   # 发送UDP报文
        print(f"Sent UDP packet, length={len(udp_data)}bytes")  #打印出发送的UDP报文长度
         
        sock.close()
        ```
        
        
        
    
4. 按**Esc** 键，输入**:wq**保存send.py文件。
5. 运行send.py文件。
   ```
   python send.py
   ```
   
6. 配置正常的情况下，后端服务器会接收到2000个A字符，即说明UDP分片报文传输成功。
 
