打开抖音互联网会发生什么-作业一

91 阅读2分钟

客户端等待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) }()
}`