Golang在Windows下使用zmq
既然看到本文章了,相信zmq是啥应该不用介绍了,先上代码吧:
package main import ( "fmt" "strconv" "time" zmq "github.com/pebbe/zmq4" ) func startServer(port int) { //REP 表示server端 socket, err := zmq.NewSocket(zmq.REP) if err != nil { fmt.Printf("Error : %v\n", err) } //Bind 绑定端口,并指定传输层协议 socket.Bind("tcp://127.0.0.1:" + strconv.Itoa(port)) fmt.Printf("bind to port %d\n", port) defer socket.Close() for { //Recv和Send必须交替进行 resp, _ := socket.Recv(0) //0表示阻塞模式 socket.Send("Hello "+resp, 0) //同步发送 } } func startClient(port int, msg string) { //REQ 表示client端 socket, err := zmq.NewSocket(zmq.REQ) if err != nil { fmt.Printf("Error : %v\n", err) } //Connect 请求建立连接,并指定传输层协议 socket.Connect("tcp://127.0.0.1:" + strconv.Itoa(port)) fmt.Println("connect to server") defer socket.Close() for i := 0; i < 10; i++ { //Send和Recv必须交替进行 socket.Send(msg, zmq.DONTWAIT) //非阻塞模式,异步发送(只是将数据写入本地buffer,并没有真正发送到网络上) resp, _ := socket.Recv(0) fmt.Printf("receive [%s]\n", resp) time.Sleep(5 * time.Second) } } func main() { go startServer(8888) time.Sleep(2 * time.Second) startClient(8888, "Hello") }
这里用的库是github.com/pebbe/zmq4
然后go mod tidy安装一下依赖,go build准备编译。。。。
好,报错了,提示gcc不在路径中
F:\Go\testzmq>go build ./src # github.com/pebbe/zmq4 cgo: C compiler "gcc" not found: exec: "gcc": executable file not found in %PATH%
找了一些资料看了一下,原来是zmq库需要使用cgo,因此需要gcc进行编译
好吧,那就先解决gcc的问题,装一个mingw64就可以了,我这里安装到了D:\devtool\mingw64目录下面
然后把D:\devtool\mingw64\bin加入到path环境变量中,就可以从任意路径调用gcc了。
gcc搞定之后,继续go build,这次提示找不到zmq.h,看来需要libzmq的开发包了
一顿折腾搞定了libzmq(此过程也很曲折,在本文结束我会把自己弄好的东西提供下载链接,减少大家的麻烦),这样libzmq的头文件、lib文件和dll都有了
一开始,我是直接把zmq.h拷贝到了Go的zmq包路径下面
我的系统里Go安装在D:\Go,所以这个路径就是D:\Go\pkg\mod\github.com\pebbe\zmq4@v1.2.9
然后继续go build,提示wrappers_windows.go无法链接,错误信息如下:
F:\Go\testzmq>go build ./src # github.com/pebbe/zmq4 C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x003.o: In function `_cgo_1e1e8b065429_Cfunc_zmq_strerror': /tmp/go-build/cgo-gcc-prolog:53: undefined reference to `__imp_zmq_strerror' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_bind': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:27: undefined reference to `__imp_zmq_bind' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:29: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_close': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:36: undefined reference to `__imp_zmq_close' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:38: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_connect': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:45: undefined reference to `__imp_zmq_connect' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:47: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_ctx_get': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:54: undefined reference to `__imp_zmq_ctx_get' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:56: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_ctx_new': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:63: undefined reference to `__imp_zmq_ctx_new' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:65: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_ctx_set': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:72: undefined reference to `__imp_zmq_ctx_set' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:74: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_ctx_term': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:81: undefined reference to `__imp_zmq_ctx_term' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:83: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_curve_keypair': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:90: undefined reference to `__imp_zmq_curve_keypair' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:92: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_curve_public': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:99: undefined reference to `__imp_zmq_curve_public' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:101: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_disconnect': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:108: undefined reference to `__imp_zmq_disconnect' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:110: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_getsockopt': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:117: undefined reference to `__imp_zmq_getsockopt' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:119: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_msg_gets': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:126: undefined reference to `__imp_zmq_msg_gets' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:128: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_msg_recv': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:135: undefined reference to `__imp_zmq_msg_recv' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:137: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_poll': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:144: undefined reference to `__imp_zmq_poll' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:146: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_proxy': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:153: undefined reference to `__imp_zmq_proxy' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:154: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_proxy_steerable': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:161: undefined reference to `__imp_zmq_proxy_steerable' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:163: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_send': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:170: undefined reference to `__imp_zmq_send' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:172: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_setsockopt': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:179: undefined reference to `__imp_zmq_setsockopt' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:181: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_socket': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:188: undefined reference to `__imp_zmq_socket' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:190: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_socket_monitor': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:197: undefined reference to `__imp_zmq_socket_monitor' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:199: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x008.o: In function `zmq4_unbind': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:206: undefined reference to `__imp_zmq_unbind' D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/wrappers_windows.go:208: undefined reference to `__imp_zmq_errno' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x009.o: In function `zmq4_get_event40': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/zmq4.go:50: undefined reference to `__imp_zmq_msg_data' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x009.o: In function `zmq4_get_event41': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/zmq4.go:57: undefined reference to `__imp_zmq_msg_data' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x009.o: In function `zmq4_get_event40': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/zmq4.go:50: undefined reference to `__imp_zmq_msg_data' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x009.o: In function `zmq4_get_event41': D:/Go/pkg/mod/github.com/pebbe/zmq4@v1.2.9/zmq4.go:57: undefined reference to `__imp_zmq_msg_data' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x009.o: In function `_cgo_1e1e8b065429_Cfunc_zmq_has': /tmp/go-build/cgo-gcc-prolog:838: undefined reference to `__imp_zmq_has' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x009.o: In function `_cgo_1e1e8b065429_Cfunc_zmq_msg_close': /tmp/go-build/cgo-gcc-prolog:857: undefined reference to `__imp_zmq_msg_close' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x009.o: In function `_cgo_1e1e8b065429_Cfunc_zmq_msg_data': /tmp/go-build/cgo-gcc-prolog:875: undefined reference to `__imp_zmq_msg_data' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x009.o: In function `_cgo_1e1e8b065429_Cfunc_zmq_msg_init': /tmp/go-build/cgo-gcc-prolog:894: undefined reference to `__imp_zmq_msg_init' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x009.o: In function `_cgo_1e1e8b065429_Cfunc_zmq_version': /tmp/go-build/cgo-gcc-prolog:911: undefined reference to `__imp_zmq_version' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x009.o: In function `_cgo_1e1e8b065429_Cfunc_zmq_z85_decode': /tmp/go-build/cgo-gcc-prolog:927: undefined reference to `__imp_zmq_z85_decode' C:\Users\ADMINI~1\AppData\Local\Temp\go-build2513089791\b043\_x009.o: In function `_cgo_1e1e8b065429_Cfunc_zmq_z85_encode': /tmp/go-build/cgo-gcc-prolog:947: undefined reference to `__imp_zmq_z85_encode' collect2.exe: error: ld returned 1 exit status F:\Go\testzmq>
看样子好像是编译gozmq库的过程中报错了。
虽然对gcc不是太熟,但是以我之前使用VC开发的经验,这个应该是没有找到libzmq的lib文件,导致无法链接
现在lib文件我已经有了,如何告诉go呢?
这里又是搞了N久,能找到的教程不多,典型的是这样的:
试了一下,并没有什么用。想想也是,好像并没有在哪里告诉gcc我要链接的lib的名字啊
后来继续找了N久,终于在github.com/pebbe/zmq4的首页说明上找到了(以后长教训了,先看官网):
Build with CGO_CFLAGS and CGO_LDFLAGS environment variables, for example: $env:CGO_CFLAGS='-ID:/dev/vcpkg/installed/x64-windows/include' $env:CGO_LDFLAGS='-LD:/dev/vcpkg/installed/x64-windows/lib -l:libzmq-mt-4_3_4.lib'
这个是指定了头文件和lib文件的目录以及lib的名称,看起来应该是对的。所以,实际上是需要libzmq的头文件和lib文件
但是,看路径就知道,上面的路径其实不是windows平台的,所以如果照搬的话,并不会成功的,比如我的libzmq安装在F盘
注意,下面的写法是错误的!!!
go env -w CGO_CFLAGS='-ID:F:\GitProjects\vcpkg\installed\x64-windows\include'
go env -w CGO_LDFLAGS="-LD:F:\GitProjects\vcpkg\installed\x64-windows\lib -l:libzmq-v141-mt-4_3_2_x64.lib"
按照这么配置,最后实际访问的路径变成了:
D:\F:\GitProjects\vcpkg\installed\x64-windows\lib\libzmq-v141-mt-4_3_2_x64.lib
D:\devtool\mingw64\lib\gcc\x86_64-w64-mingw32\8.1.0\libzmq-v141-mt-4_3_2_x64.lib
D:\devtool\mingw64\lib\gcc\libzmq-v141-mt-4_3_2_x64.lib
D:\devtool\mingw64\x86_64-w64-mingw32\lib\libzmq-v141-mt-4_3_2_x64.lib
D:\devtool\mingw64\lib\libzmq-v141-mt-4_3_2_x64.lib
D:\devtool\mingw64\x86_64-w64-mingw32\lib\libzmq-v141-mt-4_3_2_x64.lib
D:\devtool\mingw64\lib\libzmq-v141-mt-4_3_2_x64.lib
最后会得到一个提示,找不到libzmq-v141-mt-4_3_2_x64.lib
注意标红的那一条,可以看到,在Windows上这么配置是行不通的,不像Linux上所有的路径都可以从 / 开始
如果把lib文件直接扔到mingw64下面的某个lib目录里,理论上应该是可行的,试了一下确实可以,但这样的解决方案不够“完美”
但是,这也给了我们启发,如果和mingw64放在同一个分区,应该就是可以的
比如,我把zmq头文件放在 D:\devtool\zmq\libzmq-v141-x64-4_3_2
然后,先到Go的zmq包路径下面:
D:\Go\pkg\mod\github.com\pebbe\zmq4@v1.2.9
再执行两条命令:
go env -w CGO_CFLAGS='-ID:/devtool/zmq/libzmq-v141-x64-4_3_2' go env -w CGO_LDFLAGS="-LD:/devtool/zmq/libzmq-v141-x64-4_3_2 -l:libzmq-v141-mt-4_3_2_x64.lib"
然后执行go build编译gozmq库:
这次没有错误提示了,应该就是成功了
然后,再回到我们的zmq测试项目,代码如下:此时到工程目录,先go env检查一下刚才配的环境参数:
没有问题,执行编译
没有报错,那就是成功了,然后执行程序
提示缺少libzmq的dll,那么到libzmq目录下面找到dll跟编译好的程序放在同一个目录就可以了,注意有两个
再次执行,可以看到,程序正常跑起来了。
以上就是本人解决Windows平台上使用gozmq的一些问题。
最后附上Windows版本libzmq下载(版本4.3.2,包含x86和x64两个平台的版本):
https://download.csdn.net/download/achillis/86239808