欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

网络编程--Socket编程(UDP)

程序员文章站 2022-07-11 12:22:28
...

TCP和UDP对比优缺点:

TCP通信:面向连接的,可靠的数据包传输。

UDP通信:无连接的,不可靠的报文传递。

UDP通信的优点:由于无需建立连接就可以传递数据,所以传输速度远远比TCP通信快。

UDP通信的缺点:无连接,因此会丢包严重。需要在应用层封装一个协议校验传输层UDP协议的传递数据。

例如QQ,微信都是用的UDP传输协议。

TCP和UDP差异对照表:

网络编程--Socket编程(UDP)

使用场景:

              TCP:对数据传输安全性,稳定性要求较高的场合。如网络文件传输、下载、上传。

              UDP:对数据实时传输要求较高的场合。如视频直播、在线电话会议、游戏。

 

UDP服务器

 由于UDP是无连接的,所以服务器不需要额外创建socket,只需要指定好IP和port,然后监听该地址,等待客户端与之建立连接,即可通信。

1.创建server端地址结构:

    serverUdpAddr ,err := net. ResovleUDPAddr("udp","127.0.0.1:8001")

 2.创建用于通信的socket:

  UDPConn , err := net.ListenUDP("udp",serverUdpAddr)

 3.接受udp数据:

    n , cliUdpAddr , err := UDPConn.ReadFromUDP(buf)

 4.写数据到udp:

    n ,err := UDPConn.WriteToUDP("要写的数据",cliUdpAddr)

UDP客户端

  参考TCP客户端,只不过将tcp协议换成udp协议即可。如:

  net.Dial("udp","服务器的IP+port")​​

一个完整案例:

服务端代码:

package main

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

func main()  {

	//1.指定服务器的IP+port,返回一个ListenUDP()函数需要的服务器地址结构serUdpAddr
	serUdpAddr,err := net.ResolveUDPAddr("udp","127.0.0.1:8001")
	if err != nil{
		fmt.Println("net.ResolveUDPAddr err",err)
		return
	}
	fmt.Println("UDP服务器地址结构创建完成")

	//2.由上面得到的地址结构serUdpAddr,创建用于通信的socket--udpConn
	udpConn,err := net.ListenUDP("udp",serUdpAddr)
	if err != nil{
		fmt.Println("net.ListenUDP err",err)
		return
	}
    defer udpConn.Close()
	fmt.Println("UDP服务器通信socket创建完成")

	//3.读取客户端发送的数据
	buf := make([]byte,4096)
	//返回3个值,分别是读到字节数n,客户端的地址结构cliUdpAddr,错误error
	n,cliUdpAddr,err := udpConn.ReadFromUDP(buf)
	if err != nil{
		fmt.Println("udpConn.ReadFromUDP err",err)
		return
	}

	//4.打印读取到客户端的数据
	fmt.Printf("服务器读到%v的数据%s\n:",cliUdpAddr,string(buf[:n]))

	//5.回发数据(当前时间)给客户端,传入两个参数分别是要回发给客户端的数据、客户端的地址结构
	daytime := time.Now().String()
	_,err = udpConn.WriteToUDP([]byte(daytime),cliUdpAddr)
	if err != nil{
		fmt.Println("udpConn.WriteToUDP err",err)
		return
	}

}

执行结果:

网络编程--Socket编程(UDP)

客户端代码:(基本与TCP客户端的一致)

 

package main

import (
	"fmt"
	"net"
)

func main()  {

	//指定服务器IP+port,创建通信socket--conn
	conn,err := net.Dial("udp","127.0.0.1:8001")
	if err != nil{
		fmt.Println("net.Dial err:",err)
		return
	}
	defer conn.Close()

	//客户端主动写数据给服务器
	conn.Write([]byte("hello everyone!"))

	//接受服务器回发的数据
	buf:=make([]byte,4096)
	n ,err := conn.Read(buf)
	if err != nil{
		fmt.Println("conn.Read err:",err)
		return
	}
	fmt.Println("服务器回发的数据:",string(buf[:n]))

}

执行客户端后,客户端发送了一个数据,服务器收到这个数据并返回了一个时间:

网络编程--Socket编程(UDP)