Go实现TCP、UDP、HTTP通信代码示例

TCP通信需求

服务端:
服务端在本机的8888端口建立TCP监听
为接入的每一个客户端开辟一条独立的协程
循环接收客户端消息,不管客户端说什么,都自动回复“已阅xxx”
客户端:
如果客户端说的是“im off”,则回复“bye”并断开其连接
拨号连接服务端主机的8888端口,建立连接
循环从标准输入(命令行)读取一行用户输入,向服务端发送
接收并打印服务端消息,如果消息是“bye”,就退出程序

服务端:

package main

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

/*
·服务端在本机的8888端口建立TCP监听
·为接入的每一个客户端开辟一条独立的协程
·循环接收客户端消息,不管客户端说什么,都自动回复“已阅xxx”
·如果客户端说的是“im off”,则回复“bye”并断开其连接
*/

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

func main() {

	//服务端在本机的8888端口建立TCP监听
	listener, err := net.Listen("tcp", "127.0.0.1:8888")
	ServerHandleError(err, "net.Listen")

	for {
		/*循环接入所有客户端,得到专线连接*/
		conn, e := listener.Accept()
		ServerHandleError(e, "listener.Accept()")

		/*开辟一条独立协程,与该客户端聊天*/
		go ChatWith(conn)
	}

}

/*在Conn中与客户端对话*/
func ChatWith(conn net.Conn) {
	//创建消息缓冲区
	buffer := make([]byte, 1024)

	/*不断收发消息*/
	for {
		/*一个完整的消息回合*/

		//读取客户端发来的消息,存入缓冲区,消息长度为n字节
		n, err := conn.Read(buffer)
		ServerHandleError(err, "conn.Read(buffer)")

		//转换为字符串输出
		clientMsg := string(buffer[0:n])
		fmt.Printf("收到%v的消息:%s\n", conn.RemoteAddr(), clientMsg)

		//回复客户端消息:已阅或bye,bye时跳出会话
		if clientMsg != "im off" {
			conn.Write([]byte("已阅:" + clientMsg))
		} else {
			conn.Write([]byte("bye"))
			break
		}

	}

	//断开客户端连接
	conn.Close()
	fmt.Printf("客户端%s已经断开连接\n", conn.RemoteAddr())

}

客户端:

package main

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

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

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

func main() {

	//拨号远程地址,建立TCP连接
	conn, err := net.Dial("tcp", "127.0.0.1:8888")
	ClientHandleError(err, "net.Dial")

	//准备消息缓冲区
	buffer := make([]byte, 1024)

	//准备标准输入(从命令行读取用户输入)读取器
	reader := bufio.NewReader(os.Stdin)

	//源源不断地收发消息
	for {
		/*一个完整的消息回合*/

		//接收命令行输入(的一行消息)
		lineBytes, _, _ := reader.ReadLine()

		//向服务端发送
		conn.Write(lineBytes)

		//接收服务端消息,存入消息缓冲区,长度是n字节
		n, _ := conn.Read(buffer)

		//转化为字符串并打印
		serverMsg := string(buffer[0:n])
		fmt.Println("服务端:", serverMsg)

		//如果服务端说bye就退出消息循环
		if serverMsg == "bye" {
			break
		}
	}

	//客户端程序结束
	fmt.Println("GAME OVER!")

}

结果
在这里插入图片描述

UDP通信需求

服务端:
服务端在本机的8888端口建立UDP监听,得到广口连接
循环接收客户端消息,不管客户端说什么,都自动回复“已阅xxx”
如果客户端说的是“im off”,则回复“bye”xxx”
客户端:
拨号连接服务端主机的8888端口,建立UDP连接
循环从标准输入(命令行)读取一行用户输入,向服务端发送
接收并打印服务端消息,如果消息是“bye”,就退出程序

服务端:

package main

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

/*
·服务端在本机的8888端口建立UDP监听,得到广口连接
·循环接收客户端消息,不管客户端说什么,都自动回复“已阅xxx”
·如果客户端说的是“im off”,则回复“bye”
*/
func main() {
	//解析得到UDP地址
	udpAddr, err := net.ResolveUDPAddr("udp", "localhost:8888")
	ServerHandleError(err, "net.ResolveUDPAddr")

	//建立UDP监听,得到广口连接
	udpConn, err := net.ListenUDP("udp", udpAddr)
	ServerHandleError(err, "net.ListenUDP")

	//创建消息缓冲区
	buffer := make([]byte, 1024)

	//从广口连接中源源不断地读取(来自任何客户端的)数据包
	for {
		//读取一个数据包到消息缓冲区,同时获得该数据包的客户端信息
		n, remoteAddr, _ := udpConn.ReadFromUDP(buffer)

		//打印数据包消息内容
		clientMsg := string(buffer[:n])
		fmt.Printf("收到来自%v的消息:%s\n", remoteAddr, clientMsg)

		//回复该数据包的客户端
		if clientMsg != "im off"{
			udpConn.WriteToUDP([]byte("已阅:"+clientMsg), remoteAddr)
		}else{
			udpConn.WriteToUDP([]byte("fuckoff"), remoteAddr)
		}
	}

}

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

客户端:

package main

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

/*
·拨号连接服务端主机的8888端口,建立UDP连接
·循环从标准输入(命令行)读取一行用户输入,向服务端发送
·接收并打印服务端消息,如果消息是“bye”,就退出程序
*/
func main() {
	conn, e := net.Dial("udp", "127.0.0.1:8888")
	ClientHandleError(e,"net.Dial")

	reader := bufio.NewReader(os.Stdin)
	buffer := make([]byte, 1024)
	for {
		lineBytes, _, _:= reader.ReadLine()
		conn.Write(lineBytes)
		n, _ := conn.Read(buffer)
		serverMsg := string(buffer[:n])
		fmt.Println("服务端:",serverMsg)

		if serverMsg == "fuckoff"{
			conn.Write([]byte("吾去也!"))
			break
		}
	}
	fmt.Println("GAME OVER!")
}

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

结果:
D:\go_work\src\udp>Server.exe
收到来自127.0.0.1:57267的消息:test
收到来自127.0.0.1:57267的消息:im off
收到来自127.0.0.1:57267的消息:吾去也!

HTTP 发起POST、GET请求

POST请求
对https://httpbin.org/post发起post请求,携带表单数据,键值自拟,打印回复的内容

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"strings"
)

func main() {
	resp, err := http.Post("https://httpbin.org/post", "application/x-www-form-urlencoded", strings.NewReader("name=user1&age=12"))
	PostHandleError(err, "http.Post")
	defer resp.Body.Close()

	bytes, _ := ioutil.ReadAll(resp.Body)
	fmt.Println(string(bytes))
}

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

GET请求
对https://httpbin.org/get发起get请求,键值自拟,打印回复的内容

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
)

func main() {
	resp, err := http.Get("https://httpbin.org/get?name=golang")
	GetHandleError(err, "http.Get")
	defer resp.Body.Close()

	bytes, _ := ioutil.ReadAll(resp.Body)
	fmt.Println(string(bytes))
}

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值