04 | Swoole与Go系列教程之UDP服务的应用

首发原文链接: Swoole与Go系列教程之UDP服务的应用

大家好,我是码农先森。

写在前面

UDP协议相对于TCP协议而言,设计更为简单,不需要进行连接建立和断开的握手过程,也没有复杂的连接状态管理和流量控制机制。UDP协议的出现是为了满足特定类型的网络应用需求,如实时性要求高、可靠性要求低、数据传输速度要求快的场景。通过简化传输层功能和减少传输开销,UDP协议为这些应用提供了一种高效、快速的数据传输选择。

UDP 协议原理

UDP(User Datagram Protocol,用户数据报协议)是一种在计算机网络中常用的传输协议。与TCP协议相比,UDP是一种非连接型的协议,它在传输过程中不维护连接状态。UDP协议不需要在发送数据之前建立连接。每个UDP数据包(也称为数据报)都是独立的,可以独立地从源主机发送到目标主机。不提供可靠性保证,因此数据包的传输可能会丢失、损坏或以不同的顺序到达目标主机。数据包由固定大小的报头和有效负载组成。报头包含源端口号和目标端口号等信息,有效负载包含要传输的实际数据。

  • 源端口(Source Port):是指发送端使用的端口号。它是UDP数据报文头部的一个字段,用于标识发送端应用程序或进程所使用的端口。
  • 目的端口(Destination Port):是指接收端应用程序或进程等待接收UDP数据报的端口号。
  • 长度(Length):是指UDP数据报的总长度,它包括了UDP报文头部和数据部分的长度之和。
  • 校验和(Checksum):是一种用于检测数据在传输过程中是否出现错误或损坏的机制。它用于验证接收到的UDP数据报的完整性。

在 Swoole 中的应用

  1. 创建 UDP 服务对象需要指定 SWOOLE_SOCK_UDP 参数。
  2. 运行前设置进程的数量为 4,使用多进程模式。
  3. 使用 $server->on('Packet', function ($server, $data, $clientInfo){...} 接收客户端的事件。
  4. 然后使用 $server->sendto() 方法给客户端回复数据。
  5. 最后使用 $server->start(); 启动服务,开始监听。
  6. 相较于 TCP 这里不需要建立连接,则可以直接接收事件。
<?php

// 创建 UDP 服务对象
$server = new Swoole\Server('0.0.0.0', 9502, SWOOLE_PROCESS, SWOOLE_SOCK_UDP);

// 设置服务器运行时的参数
$server->set([
    'worker_num' => 4,
]);

// 监听数据接收事件
$server->on('Packet', function ($server, $data, $clientInfo) {
    echo "Received data from {$clientInfo['address']}:{$clientInfo['port']}: {$data}\n";

    // 发送响应数据给客户端
    $server->sendto($clientInfo['address'], $clientInfo['port'], 'Hello from Swoole server!');
});

// 启动服务器
$server->start();

在 Go 语言中的应用

  1. 使用 net.ListenPacket 创建 UDP 服务。
  2. 使用 conn.ReadFrom() 方法将客户端数据读入 buffer 中。
  3. 最后,使用 conn.WriteTo 回复客户端数据。
  4. 这里在处理客户端数据时,也可以直接启用一个协程来处理提高效率。
package main

import (
	"fmt"
	"net"
)

func main() {
	// 监听的地址和端口号
	addr := "127.0.0.1:8888"

	// 创建 UDP 监听器
	conn, err := net.ListenPacket("udp", addr)
	if err != nil {
		fmt.Printf("Failed to listen: %v", err)
		return
	}
	defer conn.Close()

	fmt.Printf("Listening on %s\n", addr)

	buffer := make([]byte, 1024)

	for {
		// 接收数据
		n, addr, err := conn.ReadFrom(buffer)
		if err != nil {
			fmt.Printf("Failed to read from connection: %v", err)
			break
		}

		fmt.Printf("Received data from %s: %s\n", addr.String(), string(buffer[:n]))

		// 发送响应
		_, err = conn.WriteTo([]byte("Response"), addr)
		if err != nil {
			fmt.Printf("Failed to write to connection: %v", err)
			break
		}
	}
}

总结

  1. UDP 协议是一种高效、快速传输的协议。
  2. 该协议不用进行握手,即可直接发送数据。
  3. 在使用方式上 Swoole 和 Go 其实差别并不大。
  4. 不过 Swoole 是基于回调函数进行编程的,在实现风格上有不同。
  5. Go 语言对编程方式上会更加的简洁、方便。

在这里插入图片描述

  • 24
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值