这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记
青训营最后要完成一个大项目,我们小组选择的是抖音项目,相关的接口已经提供,我们需要对这些接口进行实现,接口文档是用的protobuf写的,protobuf与语言、平台无关,其文档可以用protoc编译成C++、Java、Go等多种语言,所以需要对其进行安装。
一、安装
首先,下载protoc的压缩包,下载链接:github.com/protocolbuf…
其次,将其解压缩后里面的bin文件夹下的可执行文件protoc.exe复制到Go安装目录中的bin文件夹下
然后,安装工具protoc-gen-go,安装方法为在命令行工具中执行:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
该命令执行成功后会在GOPATH下的bin文件夹下生成可执行文件protoc-gen-go.exe。在执行该命令前,可以对go环境进行设置,防止执行出错,一般只需将GOPROXY设置为goproxy.cn,direct ,设置命令是:
go env -w GOPROXY=https://goproxy.cn,direct
这样就将protoc和编译时的必要工具安装好了。(因为我也是参考的别人的文章进行安装的,但是中间可能有些步骤出错,弄了好久才搞好,整个过程变的有点乱,这个是我后面删掉后重新搞的过程,不排除会有某些东西被我忽略的可能)
二、初步使用protoc
为了验证安装后的protoc可以正常使用,我在网上找了一个应用protobuf的客户端/服务器通信的简单demo,在两台电脑上分别编写客户端和服务器的代码。
*protobuf*
syntax="proto3";
package example;
option go_package=".;proto";
enum FOO {
X = 0;
}
message UserInfo {
string message=1;
int32 length=2;
int32 cnt=3;
}
接口文档维护客户端和服务器之间的通信,个人理解客户端和服务器的接口文档应该一致,方便用于对请求内容和响应内容的解析
对该接口文档使用protoc --go_out=. 文件名.proto进行编译,可以得到相应的Go程序文件。
*客户端程序*
package main
import (
"bufio"
"fmt"
"github.com/golang/protobuf/proto"
stProto "grpcDemo/proto"
"net"
"os"
"time"
)
func main() {
strIP := "59.79.233.9:6600" //IP是服务器的,通过IP和端口号来和服务器建立连接
var conn net.Conn
var err error
//连接服务器
for conn, err = net.Dial("tcp", strIP); err != nil; conn, err = net.Dial("tcp", strIP) {
fmt.Println("connect", strIP, "fail")
time.Sleep(time.Second)
fmt.Println("reconnect...")
}
fmt.Println("connect", strIP, "success")
defer conn.Close()
//发送消息
cnt := 0
sender := bufio.NewScanner(os.Stdin)
for sender.Scan() {
cnt++
stSend := &stProto.UserInfo{
Message: sender.Text(),
Length: *proto.Int(len(sender.Text())),
Cnt: *proto.Int(cnt),
}
//protobuf编码
pData, err := proto.Marshal(stSend)
if err != nil {
panic(err)
}
//发送数据
conn.Write(pData)
if sender.Text() == "stop" {
return
}
}
}
客户端程序主要用于向服务端程序请求连接和发送数据,服务端程序则是监听端口号,接受连接请求并接收客户端发送来的数据
*服务端程序*
package main
import (
"fmt"
"google.golang.org/protobuf/proto"
"net"
stProto "protoDemo/proto"
)
func main() {
//监听
listener, err := net.Listen("tcp", "59.79.233.9:6600") //这里的ip和端口号需要和服务端发起的请求对象一致
if err != nil {
panic(err)
}
for { //服务端要一直监听端口是否有用户发起连接请求
conn, err := listener.Accept()
if err != nil {
panic(err)
}
fmt.Println("new connect", conn.RemoteAddr())
go readMessage(conn)
}
}
//接收信息
func readMessage(conn net.Conn) {
defer conn.Close()
buf := make([]byte, 4096, 4096)
for {
//读消息
cnt, err := conn.Read(buf)
if err != nil {
panic(err)
}
stReceive := &stProto.UserInfo{}
pData := buf[:cnt]
//proto解码
err = proto.Unmarshal(pData, stReceive)
if err != nil {
panic(err)
}
fmt.Println("reveive", conn.RemoteAddr(), stReceive)
if stReceive.Message == "stop" {
//os.Exit(1) //如果用os.Exit(1),则会直接结束整个服务端程序
break //当接收到的数据为stop是,断开连接
}
}
}
两台电脑之间通过ip和端口号进行通信,可以先通过ping命令测试能够交换数据,如果能ping同则说明两者能够正常通信,以目前我的水平,只能做到两台主机处于同一局域网中的通信,还需要先将防火墙给关掉:
查看ip地址可以通过ipconfig命令:
ping ip,如果显示和下面一样则表示成功:
先启动服务端程序,然后再启动客户端程序发送数据,测试服务端是否能够接收到客户端发送过来的数据
| 启动程序 | |
|---|---|
| 发送数据 | |
|---|---|
服务端程序成功接收到客户端程序发送过来的信息,实现了两台主机的成功通信。