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

 

posted @ 2022-07-17 23:32  黑月教主  阅读(1421)  评论(1编辑  收藏  举报