Protocol(三)[UDP]

1.UDP协议

1.1.UDP协议的特性

UDP 是一个简单的传输层协议。

  • UDP 缺乏可靠性。UDP 本身不提供确认,序列号,超时重传等机制。UDP 数据报可能在网络中被复制,被重新排序。即 UDP 不保证数据报会到达其最终目的地,也不保证各个数据报的先后顺序,也不保证每个数据报只到达一次。
  • UDP 数据报是有长度的。每个 UDP 数据报都有长度,如果一个数据报正确地到达目的地,那么该数据报的长度将随数据一起传递给接收方。而 TCP 是一个字节流协议,没有任何(协议上的)记录边界。
  • UDP 是无连接的。UDP 客户和服务器之前不必存在长期的关系。UDP 发送数据报之前也不需要经过握手创建连接的过程。
  • UDP 支持多播和广播

1.2.UDP和TCP协议的区别

TCP UDP
面向连接 面向无连接
要求系统资源较多 要求系统资源较少
TCP程序结构较复杂 UDP程序结构较简单
使用流式 使用数据包式
保证数据准确性 不保证数据准确性
保证数据顺序 不保证数据顺序
通讯速度较慢 通讯速度较快

1.3.UDP和TCP协议的优缺点

协议 优点 缺点
TCP (顺序、速度)稳定、可靠 系统占用资源多、发送速度慢、开发难度大
UDP 系统占用少、发送速度快、开发难度小 (顺序、速度)不稳定、不可靠

1.4.UDP和TCP协议的使用场景

协议 使用场景
TCP 对数据稳定、准确性要求较高的场合,例如:上传、下载
UDP 对数据的传输速度要求较高的场合,允许适当的数据丢失,例如:直播、游戏、视频、在线电话

综上:
TCP:面向连接的可靠的数据包传递。 针对不稳定的网络层做完全弥补。—— 借助回执,丢包重传。

UDP:无连接的不可靠的报文传输。 针对不稳定的网络层直接还原真实状态。 —— 丢包,不处理理。

2.udp-socket编程

2.1. 并发服务器

package main

import (
	"log"
	"net"
)

func main() {
	// 1. 创建 UDP地址结构:
	udpAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:8888")
	if err != nil {
		log.Fatal(`net.ResolveUDPAddr("udp", "127.0.0.1:8888") Error:`, err.Error())
	}
	// 2. 创建 通信 socket
	udpConn, err := net.ListenUDP("udp", udpAddr)
	if err != nil {
		log.Fatalln(`net.ListenUDP("udp", udpAddr) Error:`, err.Error())
	}
	defer udpConn.Close()
	buf := make([]byte, 4096)
	for {
		// 3. 读取客户端发送数据
		n, clitAddr, err := udpConn.ReadFromUDP(buf)
		if err != nil {
			log.Fatal(`udpConn.ReadFromUDP(buf) Error:`, err.Error())
		}
		log.Println("读取到客户端发来数据:", string(buf[:n]))
		go func() {
			// 4. 发送数据给 客户端
			n, err = udpConn.WriteToUDP([]byte(buf[:n]), clitAddr)
			if err != nil {
				log.Fatal("udpConn.WriteToUDP([]byte(cbuf[:n]), clitAddr) Error:", err.Error())
			}
		}()

	}
}

2.2.客户端

package main

import (
	"log"
	"net"
	"time"
)

func main() {
	// 与服务器建立连接
	conn, err := net.Dial("udp", "127.0.0.1:8888")
	if err != nil {
		log.Fatal(`net.Dial("udp", "127.0.0.1:8888") Error:`, err.Error())
	}
	defer conn.Close()
	buf := make([]byte, 4096)
	for {
		// 写数据给服务器:写出当前地址
		conn.Write([]byte(conn.LocalAddr().String()))
		// 读服务器回发的数据
		n, err := conn.Read(buf)
		if err != nil {
			log.Fatal(`conn.Read(buf) Error:`, err.Error())
		}
		log.Println("客户端读到服务器回发:", string(buf[:n]))
		time.Sleep(time.Millisecond * 1000) // 客户端 每一秒写一次
	}

}

上一篇:通信协议(二)- TCP
下一篇:通信协议(四)- HTTP

发布了25 篇原创文章 · 获赞 11 · 访问量 2820

猜你喜欢

转载自blog.csdn.net/weixin_42366378/article/details/97576602
UDP
今日推荐