protoc的安装和初步使用|青训营笔记

1,198 阅读4分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记

青训营最后要完成一个大项目,我们小组选择的是抖音项目,相关的接口已经提供,我们需要对这些接口进行实现,接口文档是用的protobuf写的,protobuf与语言、平台无关,其文档可以用protoc编译成C++、Java、Go等多种语言,所以需要对其进行安装。

一、安装

首先,下载protoc的压缩包,下载链接:github.com/protocolbuf…

image.png

其次,将其解压缩后里面的bin文件夹下的可执行文件protoc.exe复制到Go安装目录中的bin文件夹下

protoc.jpgSDK.jpg

然后,安装工具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程序文件。

image.pngimage.png
*客户端程序*
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同则说明两者能够正常通信,以目前我的水平,只能做到两台主机处于同一局域网中的通信,还需要先将防火墙给关掉:

image.png

查看ip地址可以通过ipconfig命令:

image.png

ping ip,如果显示和下面一样则表示成功:

image.png

先启动服务端程序,然后再启动客户端程序发送数据,测试服务端是否能够接收到客户端发送过来的数据

启动程序
image.pngimage.png
发送数据
image.pngimage.png

服务端程序成功接收到客户端程序发送过来的信息,实现了两台主机的成功通信。