客户端等待ack再发包
客户端等待服务端进行响应再继续下一步的请求,同样,服务端也等待客户端请求之后再发包
服务端等待客户端请求的代码
func iflost(i int, udpAddr *net.UDPAddr, pkg []byte) {
if i == 0 {
fmt.Println("package lost")
conn, err := net.ListenUDP("udp", udpAddr)
if err != nil {
fmt.Println("ListenUDP err", err)
return
}
defer conn.Close()
_, err = conn.WriteToUDP(pkg, udpAddr)
iflost(i, udpAddr, pkg)
}
fmt.Println("没丢包,继续跑")
return
}
参数i表示从客户端收到响应的长度,只要该响应不为空,服务端就继续发送下一个包,如果该响应为空,就重新传输这个包
参数pkg表示本来要传输的包
参数UDPaddr表示给客户端发包的地址
客户端发送响应的代码
func resp(udpAddr *net.UDPAddr, len int) {
if len != 0 {
conn, err := net.ListenUDP("udp", udpAddr)
if err != nil {
fmt.Println("ListenUDP err", err)
return
}
defer conn.Close()
_, err = conn.WriteToUDP([]byte("客户端收到了你的包"), udpAddr)
fmt.Println("我回复啦")
}
return
}
参数len表示每个包的长度,如果这个长度不等于规定的长度(这里是!=0)就说明丢包了,客户端就不会回复
UDPaddr是服务端收回复的地址
为了提高效率,可以为重传的操作新建一个协程。
利用并行处理:在实现ACK过程中,可以使用多线程或多进程的方式进行并行处理,充分利用多核处理器的性能。例如,可以将发送和接收操作分别放在不同的线程或进程中进行处理,提高并发能力和效率。
服务端代码
`package main
import (
"fmt"
"net"
)
func iflost(addr *net.UDPAddr, pkg []byte) {
conn, err := net.ListenUDP("udp", addr)
if err != nil {
fmt.Println("ListenUDP err", err)
return
}
defer conn.Close()
buf := make([]byte, 1024)
//接收客户端发送过来的数据,并填充到切片buf中
n, raddr, err := conn.ReadFromUDP(buf)
if err != nil {
return
}
fmt.Println("客户端发送:", string(buf[:n]))
if n == 0 {
fmt.Println("package lost")
conn, err := net.ListenUDP("udp", raddr)
if err != nil {
fmt.Println("ListenUDP err", err)
return
}
defer conn.Close()
_, err = conn.WriteToUDP(pkg, raddr)
iflost(addr, pkg)
}
fmt.Println("没丢包,继续跑")
return
}
func main() {
//创建监听的地址,并且指定为UDP协议
udpAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:8012")
udpAddr2, err := net.ResolveUDPAddr("udp", "127.0.0.1:8013")
if err != nil {
fmt.Println("ResolveUDPAddr err:", err)
return
} //创建目标网络地址
conn, err := net.ListenUDP("udp", udpAddr)
if err != nil {
fmt.Println("ListenUDP err", udpAddr)
return
}
defer conn.Close()
buf := make([]byte, 1024)
//接收客户端发送过来的数据,并填充到切片buf中
n, raddr, err := conn.ReadFromUDP(buf)
if err != nil {
return
}
fmt.Println("客户端发送:", string(buf[:n]))
pkg1 := []byte("pkg1:123")
_, err = conn.WriteToUDP(pkg1, raddr) //向客户端发送数据
if err != nil {
fmt.Println("WriteToUDP err:", err)
return
}
go func() { iflost(udpAddr2, pkg1) }()
//第二个包
pkg2 := []byte("pkg2:456")
_, err = conn.WriteToUDP(pkg2, raddr) //向客户端发送数据
if err != nil {
fmt.Println("WriteToUDP err:", err)
return
}
go func() { iflost(udpAddr2, pkg2) }()
}`