Golang笔记:UDP基础使用与广播

这篇具有很好参考价值的文章主要介绍了Golang笔记:UDP基础使用与广播。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目的

UDP是比较基础常用的网络通讯方式,这篇文章将介绍Go语言中UDP基础使用的一些内容。

本文中使用 Packet Sender 工具进行测试,其官网地址如下:
https://packetsender.com/

基础说明

UDP是一种面向无连接的通讯,抛开业务逻辑来说UDP使用上不需要像TCP那样先建立连接才能使用,收就是收、发就是发,干净利落。

很多语言中UDP使用一般逻辑如下:

  1. 建立UDP类型Socket对象,用于数据收发;
  2. 发送时只需要指定 对方地址与端口号 就可以发送数据;
  3. 接收的话只需要监听 自身某个端口号
  4. 如果要实现双向通讯可以使用同一个Socket对象进行监听与发送;
  5. 很多时候都有一对一通讯的需求,所以标准库中都提供了一些面向连接的方法。但其实这只是在应用层面上的处理而已,实际上底层还是收就是收发就是发;

这里特别想要吐槽的一点是Go标准库使用UDP收发数据并不是给的Socket对象,而都是需要通过 UDPConn 这个对象,这个思路就是上面的第5条思路了。我个人使用UDP单发送时比较喜欢上面第2条的方式,就是单纯的发送。在Go中找了半天没有找到这种可以直接发送的方式,感觉挺变扭的。

本文中用到的一些函数与方法如下:

// 从字符串获得IP地址
func ResolveUDPAddr(network, address string) (*UDPAddr, error)

// 建立UDP(预)连接
func DialUDP(network string, laddr, raddr *UDPAddr) (*UDPConn, error)
// 启动UDP监听
func ListenUDP(network string, laddr *UDPAddr) (*UDPConn, error)

// 建立连接的情况下发送数据
func (c *UDPConn) Write(b []byte) (int, error)
// 建立连接的情况下读取数据
func (c *UDPConn) Read(b []byte) (int, error)

// 获取远程地址
func (c *UDPConn) RemoteAddr() Addr

// 接收数据并获得远程地址
func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err error)
// 向指定地址发送数据
func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error)

作为服务器使用

下面是个作为服务器使用的简单例子,功能是监听指定端口号,收到数据时输出到控制台,然后向远程端应答消息:

package main

import (
	"fmt"
	"net"
	"os"
)

func main() {
	udpAddr, err := net.ResolveUDPAddr("udp4", ":22333") // 转换地址,作为服务器使用时需要监听本机的一个端口
	                                                     // 端口号写 0 可以由系统随机分配可用的端口号
	checkError(err)
	conn, err := net.ListenUDP("udp", udpAddr) // 启动UDP监听本机端口
	checkError(err)

	for {
		var buf [128]byte
		len, addr, err := conn.ReadFromUDP(buf[:]) // 读取数据,返回值依次为读取数据长度、远端地址、错误信息 // 读取操作会阻塞直至有数据可读取
		checkError(err)
		fmt.Println(string(buf[:len])) // 向终端打印收到的消息

		_, err = conn.WriteToUDP([]byte("233~~~"), addr) // 写数据,返回值依次为写入数据长度、错误信息 // WriteToUDP()并非只能用于应答的,只要有个远程地址可以随时发消息
		checkError(err)
	}
}

func checkError(err error) {
	if err != nil {
		fmt.Fprintf(os.Stderr, "Fatal error %s", err.Error())
		os.Exit(1)
	}
}

golang udp,编程相关,udp,golang,网络,广播,socket

作为客户端使用

作为客户端使用也不复杂,下面是个简单的示例:

package main

import (
	"fmt"
	"net"
	"os"
	"time"
)

func main() {
	udpAddr, err := net.ResolveUDPAddr("udp4", "192.168.31.189:53771") // 转换地址,作为客户端使用要向远程发送消息,这里用远程地址与端口号
	checkError(err)
	conn, err := net.DialUDP("udp", nil, udpAddr) // 建立连接,第二个参数为nil时通过默认本地地址(猜测可能是第一个可用的地址,未进行测试)发送且端口号自动分配,第三个参数为远程端地址与端口号
	checkError(err)

	go receive(conn) // 使用DialUDP建立连接后也可以监听来自远程端的数据

	for {
		_, err = conn.Write([]byte("naisu233~~~")) // 向远程端发送消息
		checkError(err)
		time.Sleep(4 * time.Second) // 等待4s
	}
}

func receive(conn *net.UDPConn) {
	for {
		var buf [128]byte
		len, err := conn.Read(buf[0:]) // 读取数据 // 读取操作会阻塞直至有数据可读取
		checkError(err)
		fmt.Println(string(buf[0:len]))
	}
}

func checkError(err error) {
	if err != nil {
		fmt.Fprintf(os.Stderr, "Fatal error %s", err.Error())
		os.Exit(1)
	}
}

golang udp,编程相关,udp,golang,网络,广播,socket

广播

广播主要就是指发送时向内网中所有设备发送消息了,操作上最主要就是发送消息时地址使用 广播地址 ,广播地址计算方式可以参考下面文章:

《UDP IPv4广播地址计算(附Node.js示例代码)》
https://blog.csdn.net/Naisu_kun/article/details/127221349

下面是Go中广播地址获取代码:

// 返回广播地址列表
func GetBroadcastAddress() ([]string, error) {
	broadcastAddress := []string{}

	interfaces, err := net.Interfaces() // 获取所有网络接口
	if err != nil {
		return broadcastAddress, err
	}

	for _, face := range interfaces {
		// 选择 已启用的、能广播的、非回环 的接口
		if (face.Flags & (net.FlagUp | net.FlagBroadcast | net.FlagLoopback)) == (net.FlagBroadcast | net.FlagUp) {
			addrs, err := face.Addrs() // 获取该接口下IP地址
			if err != nil {
				return broadcastAddress, err
			}
			for _, addr := range addrs {
				if ipnet, ok := addr.(*net.IPNet); ok { // 转换成 IPNet { IP Mask } 形式
					if ipnet.IP.To4() != nil { // 只取IPv4的
						var fields net.IP // 用于存放广播地址字段(共4个字段)
						for i := 0; i < 4; i++ {
							fields = append(fields, (ipnet.IP.To4())[i]|(^ipnet.Mask[i])) // 计算广播地址各个字段
						}
						broadcastAddress = append(broadcastAddress, fields.String()) // 转换为字符串形式
					}
				}
			}
		}
	}

	return broadcastAddress, nil
}

因为工作原因我的电脑上有非常多的实体的或是虚拟的网卡,下面是我电脑上部分网络情况:
golang udp,编程相关,udp,golang,网络,广播,socket
golang udp,编程相关,udp,golang,网络,广播,socket
golang udp,编程相关,udp,golang,网络,广播,socket

下面是广播地址获取演示:
golang udp,编程相关,udp,golang,网络,广播,socket

需要注意的是如果设备上有多个网卡的话就可能有多个广播地址,要全局广播的话就要向每个广播地址分别发送消息。操作上来说可以用服务器的方式,拿到 UDPConn 对象后使用 WriteToUDP 方法分别向各个广播地址发送消息。

总结

UDP的使用比较简单,这里没有提及的是组播和任意播功能,因为我不太用这两种所以这里也就不介绍了。文章来源地址https://www.toymoban.com/news/detail-701860.html

到了这里,关于Golang笔记:UDP基础使用与广播的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux网络编程系列之UDP广播

            1、 Linux网络编程系列之网络编程基础         2、 Linux网络编程系列之TCP协议编程         3、 Linux网络编程系列之UDP协议编程         4、 Linux网络编程系列之UDP广播         5、 Linux网络编程系列之UDP组播         6、 Linux网络编程系列之服务器编程——阻塞IO模型

    2024年02月04日
    浏览(37)
  • Qt网络编程 (udp广播和接收例)

    使用两个项目 1 sender 用来广播\\\"hello world\\\"; 2 receiver 用来接收广播信息 1 创建Qdialog类 2 在sender.pro 中添加 QT +=network 一行代码 3 在sender.h 中声明类 class QUdpSocket; 在声明一个私有对象 QUdpSocket *sender; 4 在ui界面拖入一个按钮 用来触发广播信息 其槽函数如下 在sender.cpp 构造函数中添

    2024年02月11日
    浏览(40)
  • 编程笔记 Golang基础 012 项目构建

    如何构建和组织一个项目,是学习该语言编程的开始。 Go 语言中的模块(Module)、包(Package)和文件有着紧密的关系,它们共同构成了 Go 语言的代码组织结构和依赖管理机制: 模块(Module) : Go 语言从 1.11 版本开始引入了模块系统,用于管理和解决依赖问题。 模块是一个

    2024年02月21日
    浏览(38)
  • 编程笔记 Golang基础 010 常量和变量

    在 Go 语言中,常量(Constant)是一个固定的值,在程序运行期间不可被修改。它们通常用来表示那些在整个程序执行过程中不会变化的数值或其他类型的数据。在 Go 语言中,变量是用来存储数据的容器。 在 Go 语言中,常量(Constant)是一个固定的值,在程序运行期间不可被

    2024年02月21日
    浏览(45)
  • QT网络编程之实现UDP广播发送和接收

    一.UDP广播介绍 UDP广播地址固定IP地址为:XXX.XXX.XXX.255。 如果向全网段发送广播消息,那么广播地址为:255.255.255.255; 如果向单个网段发送广播消息,例如你的IP是192.168.31.104,那么广播地址为192.168.31.255。 广播消息接收方需要绑定0.0.0.0地址并监听指定端口即可收到广播的群

    2024年03月25日
    浏览(61)
  • UDP的一对多通信(广播)-----个人笔记

    补充: 1、 TCP通信采用一对一的通信模式。日常生活中的网络会议通知、广告、网络信息公告等功能,需要采用UDP实现一对多的群发功能。         通过Internet实现群发功能的形式有两种: (1)利用 广播 向子网中的所有客户发送消息,比如各类通知、单位公告、集体活动日

    2024年02月05日
    浏览(34)
  • 编程笔记 Golang基础 016 数据类型:数字类型

    在Go语言中,数字类型是其丰富数据类型的一部分,主要用于表示数值。 以下是Go语言中主要的数字类型详解: 1. 整数类型(Integer Types) a) 固定长度整数: 有符号整数 : int8 :8位带符号整数,范围从-128到127。 int16 :16位带符号整数,范围从-32,768到32,767。 int32 :32位带符号

    2024年02月22日
    浏览(45)
  • 编程笔记 Golang基础 011 控制台输入与输出

    Golang控制台输入与输入是用内置的 fmt 包来完成的。初学时要经常用到。 在软件开发工具(如Goland)中,控制台通常指的是集成开发环境(IDE)中的一个组件或面板,它模拟了命令行界面(CLI),允许开发者直接在IDE内部运行和调试程序,以及与操作系统进行交互。这个“控

    2024年02月20日
    浏览(54)
  • JavaCV音视频开发宝典:UDP广播推流 使用UDP方式推送广播TS流 实现UDP一对多广播

    《JavaCV音视频开发宝典》专栏目录导航 《JavaCV音视频开发宝典》专栏介绍和目录 ​ 在之前文章中我们已经实现rtp点到点传输JavaCV音视频开发宝典:rtp点到点音视频传输(一对一音视频直播)和rtp广播JavaCV音视频开发宝典:rtp广播方式发送TS流音视频传输(一对多音视频会议

    2023年04月08日
    浏览(56)
  • C++开发基础之网络编程WinSock库使用详解TCP/UDP Socket开发

    Winsock是Windows操作系统提供的用于网络编程的API库。它是Windows Sockets的简称,也就是套接字库。Winsock可以让开发人员使用TCP/IP协议族中的各种协议,如TCP、UDP等,在Windows平台下进行网络编程。 Winsock提供了一组函数和数据结构,这些函数和数据结构可以让开发人员创建和管理

    2024年01月23日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包