利用Go制作一个基于UDP协议的客户端服务端通信程序|Go主题月

1,135 阅读2分钟

要说的东西都写在注释里面啦

需求:

服务端在本机的8888端口建立UDP监听

循环接收客户端消息,不管客户端说什么,都自动回复“已阅xxx”

如果客户端说的是“im off ”,则回复“bye”并断开连接

拨号连接服务端主机的8888端口,建立连接

循环从标准输入(命令行)读取一行用户输入,向服务端发送

接收并打印服务端信息,如果消息是“bye”,则退出程序

我们先简单实现基于UDP协议的通信。

package main

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

func ServerHandleError(err error,when string) {
	if err != nil {
		fmt.Println(err,when)
		os.Exit(1)
	}
}
func main() {
	//解析得到UDP地址
	udpAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:8888")
	ServerHandleError(err,"net.ResolveIPAddr")

	//在UDP地址上建立UDP监听,得到连接
	udpConn, err := net.ListenUDP("udp", udpAddr)
	ServerHandleError(err,"net.Listen")

	defer udpConn.Close()
	//建立缓冲区
	buffer := make([]byte,1024)
	//使用连接IO
	//从连接中读入内容,丢入缓冲区
	n, remoteAddr, err := udpConn.ReadFromUDP(buffer)
	ServerHandleError(err,"ReadFromUDP")
	fmt.Printf("读到来自%v的内容:%s\n",remoteAddr,string(buffer[:n]))

	//向客户端写出内容
	udpConn.WriteToUDP([]byte("朕已阅!"),remoteAddr)
}
package main

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

func ClientHandleError(err error,when string) {
	if err != nil {
		fmt.Println(err,when)
		os.Exit(1)
	}
}

func main() {
	//拨号请求连接
	conn, err := net.Dial("udp", "127.0.0.1:8888")
	ClientHandleError(err,"net.Dial")

	defer conn.Close()

	//拿着连接IO

	//向连接中写出信息

	n, err := conn.Write([]byte("只有main包下的main函数才能运行啊"))
	ClientHandleError(err,"conn.Write")
	fmt.Printf("成功写出%d个字节\n",n)

	//创建缓冲区
	buffer := make([]byte, 1024)
	n, err = conn.Read(buffer)
	ClientHandleError(err,"conn.Read")
	fmt.Println(string(buffer[:n]))
}

image.png

image.png

改进后:

package main
/*
需求:

服务端在本机的8888端口建立UDP监听
循环接收客户端消息,不管客户端说什么,都自动回复“已阅xxx”
如果客户端说的是“im off ”,则回复“bye”并断开连接

拨号连接服务端主机的8888端口,建立连接
循环从标准输入(命令行)读取一行用户输入,向服务端发送
接收并打印服务端信息,如果消息是“bye”,则退出程序
*/
import (
	"fmt"
	"net"
	"os"
)


func ServerHandleError(err error,when string) {
	if err != nil {
		fmt.Println(err,when)
		os.Exit(1)
	}
}
func main() {
	//解析得到UDP地址
	udpAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:8888")
	ServerHandleError(err,"net.ResolveIPAddr")

	//在UDP地址上建立UDP监听,得到连接
	udpConn, err := net.ListenUDP("udp", udpAddr)
	ServerHandleError(err,"net.Listen")

	defer udpConn.Close()
	//建立缓冲区
	buffer := make([]byte,1024)
	//使用连接IO
	//从连接中读入内容,丢入缓冲区
	for{
		n, remoteAddr, err := udpConn.ReadFromUDP(buffer)
		ServerHandleError(err,"ReadFromUDP")
		clientMsg := string(buffer[:n])
		fmt.Printf("读到来自%v的内容:%s\n",remoteAddr,clientMsg)

		//向客户端写出内容
		if clientMsg != "im off"{
			udpConn.WriteToUDP([]byte("朕已阅!"+clientMsg), remoteAddr)

		}else{
			udpConn.WriteToUDP([]byte("bye"),remoteAddr)
		}
	}

}
package main

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

func ClientHandleError(err error,when string) {
	if err != nil {
		fmt.Println(err,when)
		os.Exit(1)
	}
}

func main() {
	//拨号请求连接
	conn, err := net.Dial("udp", "127.0.0.1:8888")
	ClientHandleError(err,"net.Dial")

	defer conn.Close()
	//创建缓冲区
	buffer := make([]byte, 1024)
	reader := bufio.NewReader(os.Stdin)
	for{
		lineBytes, _, _ := reader.ReadLine()
		//向连接中写出信息
		n, err := conn.Write(lineBytes)
		ClientHandleError(err,"conn.Write")

		fmt.Printf("成功写出%d个字节\n",n)

		n, err = conn.Read(buffer)
		ClientHandleError(err,"conn.Read")
		fmt.Println("服务端:"+string(buffer[:n]))

		if string(buffer[:n]) == "fuckoff"{
			conn.Write([]byte("呜呜呜"))
			break
		}

	}
	fmt.Println("game over!")

}

image.png

image.png