{"id":2878,"date":"2019-02-22T23:07:03","date_gmt":"2019-02-22T15:07:03","guid":{"rendered":"https:\/\/damogame.cn:15443\/wordpress\/?p=2878"},"modified":"2019-02-22T23:08:24","modified_gmt":"2019-02-22T15:08:24","slug":"golang%e4%bd%bf%e7%94%a8protobuf-2","status":"publish","type":"post","link":"https:\/\/i007.cc\/wordpress\/archives\/2878","title":{"rendered":"golang\u4f7f\u7528protobuf"},"content":{"rendered":"<div class=\"post-topheader custom- pt0\">\n<div class=\"mb20\">\n<div class=\"block-for-right-border\">\n<div class=\"row\">\n<div class=\"col-md-12 col-sm-12 col-xs-12\">\n<div class=\"post-topheader__info\" data-username=\"\u82b1\u95f4\u9690\u864e\" data-userslug=\"huajianyinhu\" data-useravatar=\"https:\/\/cdn.segmentfault.com\/v-5c6fbb96\/global\/img\/user-64.png\"><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"article fmt article__content\" data-id=\"1190000009277748\" data-license=\"\">\n<h1 id=\"articleHeader0\">\u4e3a\u4ec0\u4e48\u8981\u4f7f\u7528protobuf<\/h1>\n<p>\u6700\u8fd1\u7684\u9879\u76ee\u4e2d\uff0c\u4e00\u76f4\u4f7f\u7528Json\u505a\u6570\u636e\u4f20\u8f93\u3002Json\u7528\u8d77\u6765\u7684\u786e\u5f88\u65b9\u4fbf\u3002\u4f46\u76f8\u5bf9\u4e8eprotobuf\u6570\u636e\u91cf\u66f4\u5927\u4e9b\u3002\u505a\u4e00\u4e2a\u79fb\u52a8\u7aef\u5e94\u7528\uff0c\u4e3a\u7528\u6237\u7701\u70b9\u6d41\u91cf\u8fd8\u662f\u5f88\u6709\u5fc5\u8981\u7684\u3002\u6b63\u597d\u4e5f\u53ef\u4ee5\u5b66\u4e60\u4e00\u4e0bprotobuf\u7684\u4f7f\u7528<\/p>\n<p>\u8ddfJson\u76f8\u6bd4protobuf\u6027\u80fd\u66f4\u9ad8\uff0c\u66f4\u52a0\u89c4\u8303<\/p>\n<ul>\n<li>\u7f16\u89e3\u7801\u901f\u5ea6\u5feb\uff0c\u6570\u636e\u4f53\u79ef\u5c0f<\/li>\n<li>\u4f7f\u7528\u7edf\u4e00\u7684\u89c4\u8303\uff0c\u4e0d\u7528\u518d\u62c5\u5fc3\u5927\u5c0f\u5199\u4e0d\u540c\u5bfc\u81f4\u89e3\u6790\u5931\u8d25\u7b49\u86cb\u75bc\u7684\u95ee\u9898\u4e86<\/li>\n<\/ul>\n<p>\u4f46\u4e5f\u5931\u53bb\u4e86\u4e00\u4e9b\u4fbf\u5229\u6027<\/p>\n<ul>\n<li>\u6539\u52a8\u534f\u8bae\u5b57\u6bb5\uff0c\u9700\u8981\u91cd\u65b0\u751f\u6210\u6587\u4ef6\u3002<\/li>\n<li>\u6570\u636e\u6ca1\u6709\u53ef\u8bfb\u6027<\/li>\n<\/ul>\n<h1 id=\"articleHeader1\">\u5b89\u88c5<\/h1>\n<p>\u5728go\u4e2d\u4f7f\u7528protobuf\uff0c\u6709\u4e24\u4e2a\u53ef\u9009\u7528\u7684\u5305goprotobuf\uff08go\u5b98\u65b9\u51fa\u54c1\uff09\u548cgogoprotobuf\u3002<br \/>\ngogoprotobuf\u5b8c\u5168\u517c\u5bb9google protobuf\uff0c\u5b83\u751f\u6210\u7684\u4ee3\u7801\u8d28\u91cf\u548c\u7f16\u89e3\u7801\u6027\u80fd\u5747\u6bd4goprotobuf\u9ad8\u4e00\u4e9b<\/p>\n<h2 id=\"articleHeader2\">\u5b89\u88c5protoc<\/h2>\n<p>\u9996\u5148\u53bb<a href=\"https:\/\/github.com\/google\/protobuf\/releases\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https:\/\/github.com\/google\/pro&#8230;<\/a>\u00a0\u4e0a\u4e0b\u8f7dprotobuf\u7684\u7f16\u8bd1\u5668protoc\uff0cwindows\u4e0a\u53ef\u4ee5\u76f4\u63a5\u4e0b\u5230exe\u6587\u4ef6(linux\u5219\u9700\u8981\u7f16\u8bd1)\uff0c\u6700\u540e\u5c06\u4e0b\u8f7d\u597d\u7684\u53ef\u6267\u884c\u6587\u4ef6\u62f7\u8d1d\u5230$GOPATH\u7684bin\u76ee\u5f55\u4e0b($GOPATH\/bin\u76ee\u5f55\u6700\u597d\u6dfb\u52a0\u5230\u7cfb\u7edf\u73af\u5883\u53d8\u91cf\u91cc)<\/p>\n<h2 id=\"articleHeader3\">\u5b89\u88c5protobuf\u5e93\u6587\u4ef6<\/h2>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">go get github.com\/golang\/protobuf\/proto<\/pre>\n<p>&nbsp;<\/p>\n<h2 id=\"articleHeader4\">goprotobuf<\/h2>\n<h3 id=\"articleHeader5\">\u5b89\u88c5\u63d2\u4ef6<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">go get github.com\/golang\/protobuf\/protoc-gen-go<\/pre>\n<p>&nbsp;<\/p>\n<h3 id=\"articleHeader6\">\u751f\u6210go\u6587\u4ef6<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">protoc --go_out=. *.proto<\/pre>\n<p>&nbsp;<\/p>\n<h2 id=\"articleHeader7\">gogoprotobuf<\/h2>\n<h3 id=\"articleHeader8\">\u5b89\u88c5\u63d2\u4ef6<\/h3>\n<p>gogoprotobuf\u6709\u4e24\u4e2a\u63d2\u4ef6\u53ef\u4ee5\u4f7f\u7528<\/p>\n<ul>\n<li>protoc-gen-gogo\uff1a\u548cprotoc-gen-go\u751f\u6210\u7684\u6587\u4ef6\u5dee\u4e0d\u591a\uff0c\u6027\u80fd\u4e5f\u51e0\u4e4e\u4e00\u6837(\u7a0d\u5fae\u5feb\u4e00\u70b9\u70b9)<\/li>\n<li>protoc-gen-gofast\uff1a\u751f\u6210\u7684\u6587\u4ef6\u66f4\u590d\u6742\uff0c\u6027\u80fd\u4e5f\u66f4\u9ad8(\u5feb5-7\u500d)<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">\/\/gogo\r\ngo get github.com\/gogo\/protobuf\/protoc-gen-gogo\r\n\r\n\/\/gofast\r\ngo get github.com\/gogo\/protobuf\/protoc-gen-gofast<\/pre>\n<p>&nbsp;<\/p>\n<h3 id=\"articleHeader9\">\u5b89\u88c5gogoprotobuf\u5e93\u6587\u4ef6<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">go get github.com\/gogo\/protobuf\/proto\r\ngo get github.com\/gogo\/protobuf\/gogoproto  \/\/\u8fd9\u4e2a\u4e0d\u88c5\u4e5f\u6ca1\u5173\u7cfb<\/pre>\n<p>&nbsp;<\/p>\n<h3 id=\"articleHeader10\">\u751f\u6210go\u6587\u4ef6<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">\/\/gogo\r\nprotoc --gogo_out=. *.proto\r\n\r\n\/\/gofast\r\nprotoc --gofast_out=. *.proto<\/pre>\n<p>&nbsp;<\/p>\n<h1 id=\"articleHeader11\">\u6027\u80fd\u6d4b\u8bd5<\/h1>\n<p>\u8fd9\u91cc\u53ea\u662f\u7b80\u5355\u7684\u7528go test\u6d4b\u8bd5\u4e86\u4e00\u4e0b<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">\/\/goprotobuf\r\n\"\u7f16\u7801\"\uff1a447ns\/op\r\n\"\u89e3\u7801\"\uff1a422ns\/op\r\n\r\n\/\/gogoprotobuf-go\r\n\"\u7f16\u7801\"\uff1a433ns\/op\r\n\"\u89e3\u7801\"\uff1a427ns\/op\r\n\r\n\/\/gogoprotobuf-fast\r\n\"\u7f16\u7801\"\uff1a112ns\/op\r\n\"\u89e3\u7801\"\uff1a112ns\/op<\/pre>\n<p>&nbsp;<\/p>\n<h1 id=\"articleHeader12\">go_protobuf\u7684\u7b80\u5355\u4f7f\u7528<\/h1>\n<h2 id=\"articleHeader13\">test.proto<\/h2>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">syntax = \"proto3\";  \/\/\u6307\u5b9a\u7248\u672c\uff0c\u5fc5\u987b\u8981\u5199\uff08proto3\u3001proto2\uff09  \r\npackage proto;\r\n\r\nenum FOO \r\n{ \r\n    X = 0; \r\n};\r\n\r\n\/\/message\u662f\u56fa\u5b9a\u7684\u3002UserInfo\u662f\u7c7b\u540d\uff0c\u53ef\u4ee5\u968f\u610f\u6307\u5b9a\uff0c\u7b26\u5408\u89c4\u8303\u5373\u53ef\r\nmessage UserInfo{\r\n    string message = 1;   \/\/\u6d88\u606f\r\n    int32 length = 2;    \/\/\u6d88\u606f\u5927\u5c0f\r\n    int32 cnt = 3;      \/\/\u6d88\u606f\u8ba1\u6570\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<h2 id=\"articleHeader14\">client_protobuf.go<\/h2>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">package main\r\n\r\nimport (\r\n    \"bufio\"\r\n    \"fmt\"\r\n    \"net\"\r\n    \"os\"\r\n    stProto \"proto\"\r\n    \"time\"\r\n\r\n    \/\/protobuf\u7f16\u89e3\u7801\u5e93,\u4e0b\u9762\u4e24\u4e2a\u5e93\u662f\u76f8\u4e92\u517c\u5bb9\u7684\uff0c\u53ef\u4ee5\u4f7f\u7528\u5176\u4e2d\u4efb\u610f\u4e00\u4e2a\r\n    \"github.com\/golang\/protobuf\/proto\"\r\n    \/\/\"github.com\/gogo\/protobuf\/proto\"\r\n)\r\n\r\nfunc main() {\r\n    strIP := \"localhost:6600\"\r\n    var conn net.Conn\r\n    var err error\r\n\r\n    \/\/\u8fde\u63a5\u670d\u52a1\u5668\r\n    for conn, err = net.Dial(\"tcp\", strIP); err != nil; conn, err = net.Dial(\"tcp\", strIP) {\r\n        fmt.Println(\"connect\", strIP, \"fail\")\r\n        time.Sleep(time.Second)\r\n        fmt.Println(\"reconnect...\")\r\n    }\r\n    fmt.Println(\"connect\", strIP, \"success\")\r\n    defer conn.Close()\r\n\r\n    \/\/\u53d1\u9001\u6d88\u606f\r\n    cnt := 0\r\n    sender := bufio.NewScanner(os.Stdin)\r\n    for sender.Scan() {\r\n        cnt++\r\n        stSend := &amp;stProto.UserInfo{\r\n            Message: sender.Text(),\r\n            Length:  *proto.Int(len(sender.Text())),\r\n            Cnt:     *proto.Int(cnt),\r\n        }\r\n\r\n        \/\/protobuf\u7f16\u7801\r\n        pData, err := proto.Marshal(stSend)\r\n        if err != nil {\r\n            panic(err)\r\n        }\r\n\r\n        \/\/\u53d1\u9001\r\n        conn.Write(pData)\r\n        if sender.Text() == \"stop\" {\r\n            return\r\n        }\r\n    }\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<h2 id=\"articleHeader15\">server_protobuf.go<\/h2>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">package main\r\n\r\nimport (\r\n    \"fmt\"\r\n    \"net\"\r\n    \"os\"\r\n    stProto \"proto\"\r\n\r\n    \/\/protobuf\u7f16\u89e3\u7801\u5e93,\u4e0b\u9762\u4e24\u4e2a\u5e93\u662f\u76f8\u4e92\u517c\u5bb9\u7684\uff0c\u53ef\u4ee5\u4f7f\u7528\u5176\u4e2d\u4efb\u610f\u4e00\u4e2a\r\n    \"github.com\/golang\/protobuf\/proto\"\r\n    \/\/\"github.com\/gogo\/protobuf\/proto\"\r\n)\r\n\r\nfunc main() {\r\n    \/\/\u76d1\u542c\r\n    listener, err := net.Listen(\"tcp\", \"localhost:6600\")\r\n    if err != nil {\r\n        panic(err)\r\n    }\r\n\r\n    for {\r\n        conn, err := listener.Accept()\r\n        if err != nil {\r\n            panic(err)\r\n        }\r\n        fmt.Println(\"new connect\", conn.RemoteAddr())\r\n        go readMessage(conn)\r\n    }\r\n}\r\n\r\n\/\/\u63a5\u6536\u6d88\u606f\r\nfunc readMessage(conn net.Conn) {\r\n    defer conn.Close()\r\n    buf := make([]byte, 4096, 4096)\r\n    for {\r\n        \/\/\u8bfb\u6d88\u606f\r\n        cnt, err := conn.Read(buf)\r\n        if err != nil {\r\n            panic(err)\r\n        }\r\n\r\n        stReceive := &amp;stProto.UserInfo{}\r\n        pData := buf[:cnt]\r\n\r\n        \/\/protobuf\u89e3\u7801\r\n        err = proto.Unmarshal(pData, stReceive)\r\n        if err != nil {\r\n            panic(err)\r\n        }\r\n\r\n        fmt.Println(\"receive\", conn.RemoteAddr(), stReceive)\r\n        if stReceive.Message == \"stop\" {\r\n            os.Exit(1)\r\n        }\r\n    }\r\n}<\/pre>\n<\/div>\n<div class=\"clearfix mt10\">\n<div class=\"pull-right mt-10 hidden-xs\">\n<div class=\"widget-share__full\" data-text=\"golang\u4f7f\u7528protobuf\" data-url=\"https:\/\/segmentfault.com\/a\/1190000009277748\" data-shorturl=\"http:\/\/sfau.lt\/b5M5Jg\">\n<div class=\"widget-share-network sharer-0\">\n<p>&nbsp;<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u4e3a\u4ec0\u4e48\u8981\u4f7f\u7528protobuf \u6700\u8fd1\u7684\u9879\u76ee<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"colormag_page_container_layout":"default_layout","colormag_page_sidebar_layout":"default_layout","footnotes":""},"categories":[],"tags":[122],"class_list":["post-2878","post","type-post","status-publish","format-standard","hentry","tag-06-godocker"],"_links":{"self":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/posts\/2878","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/comments?post=2878"}],"version-history":[{"count":0,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/posts\/2878\/revisions"}],"wp:attachment":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/media?parent=2878"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/categories?post=2878"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/tags?post=2878"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}