Files

msys2 ucrt64 gcc 설치

go 프로젝트 폴더로 복사

C:\Users\j\+win\vcpkg\packages\zeromq_x64-windows\bin\libzmq-mt-4_3_5.dll
set CGO_ENABLED=1
go run server.go

server.go

package main

/*
#cgo CFLAGS: -IC:/Users/j/+win/vcpkg/packages/zeromq_x64-windows/include
#cgo LDFLAGS: -LC:/Users/j/+win/vcpkg/packages/zeromq_x64-windows/lib -lzmq-mt-4_3_5
#include <zmq.h>
*/
import "C"
import (
    "fmt"
    "unsafe"
)
func main() {
	context := C.zmq_ctx_new()
	defer C.zmq_ctx_term(context)

	socket := C.zmq_socket(context, C.ZMQ_REP)
	defer C.zmq_close(socket)

	C.zmq_bind(socket, C.CString("tcp://*:5555"))

	for {
			msg := C.zmq_msg_t{}
			C.zmq_msg_init(&msg)
			defer C.zmq_msg_close(&msg)

			C.zmq_msg_recv(&msg, socket, 0)
			size := C.zmq_msg_size(&msg)
			data := C.zmq_msg_data(&msg)

			goData := C.GoBytes(data, C.int(size))
			fmt.Printf("Received: %s\n", string(goData))

			C.zmq_send(socket, unsafe.Pointer(&goData[0]), C.size_t(len(goData)), 0)
	}
}

client.py

import zmq
import time

context = zmq.Context()

print("Connecting to server...")
socket = context.socket(zmq.REQ)
socket.connect("tcp://localhost:5555")

for request in range(10):
    print(f"Sending request {request} ...")
    socket.send(f"Hello {request}".encode())

    #  Get the reply.
    message = socket.recv()
    print(f"Received reply {request} [ {message.decode()} ]")

    # Wait for a second before next request
    time.sleep(1)

wrapper server.go

package main

/*
#cgo CFLAGS: -IC:/Users/j/+win/vcpkg/packages/zeromq_x64-windows/include
#cgo LDFLAGS: -LC:/Users/j/+win/vcpkg/packages/zeromq_x64-windows/lib -lzmq-mt-4_3_5
#include <zmq.h>
#include <stdlib.h>
*/
import "C"
import (
    "fmt"
    "unsafe"
)

// 타입 별칭
type (
    ZmqContext unsafe.Pointer
    ZmqSocket  unsafe.Pointer
    ZmqMsg     C.zmq_msg_t
)

// 상수
const (
    ZMQ_REP = C.ZMQ_REP
)

// 래퍼 함수들
func zmq_ctx_new() ZmqContext {
    return ZmqContext(C.zmq_ctx_new())
}

func zmq_ctx_term(context ZmqContext) {
    C.zmq_ctx_term(unsafe.Pointer(context))
}

func zmq_socket(context ZmqContext, typ int) ZmqSocket {
    return ZmqSocket(C.zmq_socket(unsafe.Pointer(context), C.int(typ)))
}

func zmq_close(socket ZmqSocket) {
    C.zmq_close(unsafe.Pointer(socket))
}

func zmq_bind(socket ZmqSocket, endpoint string) {
    cEndpoint := C.CString(endpoint)
    defer C.free(unsafe.Pointer(cEndpoint))
    C.zmq_bind(unsafe.Pointer(socket), cEndpoint)
}

func zmq_msg_init(msg *ZmqMsg) {
    C.zmq_msg_init((*C.zmq_msg_t)(msg))
}

func zmq_msg_close(msg *ZmqMsg) {
    C.zmq_msg_close((*C.zmq_msg_t)(msg))
}

func zmq_msg_recv(msg *ZmqMsg, socket ZmqSocket, flags int) {
    C.zmq_msg_recv((*C.zmq_msg_t)(msg), unsafe.Pointer(socket), C.int(flags))
}

func zmq_msg_size(msg *ZmqMsg) int {
    return int(C.zmq_msg_size((*C.zmq_msg_t)(msg)))
}

func zmq_msg_data(msg *ZmqMsg) unsafe.Pointer {
    return C.zmq_msg_data((*C.zmq_msg_t)(msg))
}

func zmq_send(socket ZmqSocket, data []byte, flags int) {
    C.zmq_send(unsafe.Pointer(socket), unsafe.Pointer(&data[0]), C.size_t(len(data)), C.int(flags))
}

// 새로운 래퍼 함수: ZmqMsg에서 Go 바이트 슬라이스로 변환
func zmq_msg_to_bytes(msg *ZmqMsg) []byte {
    size := zmq_msg_size(msg)
    data := zmq_msg_data(msg)
    return C.GoBytes(data, C.int(size))
}

func main() {
    context := zmq_ctx_new()
    defer zmq_ctx_term(context)

    socket := zmq_socket(context, ZMQ_REP)
    defer zmq_close(socket)

    zmq_bind(socket, "tcp://*:5555")

    for {
        msg := ZmqMsg{}
        zmq_msg_init(&msg)
        defer zmq_msg_close(&msg)

        zmq_msg_recv(&msg, socket, 0)
        goData := zmq_msg_to_bytes(&msg)
        fmt.Printf("Received: %s\n", string(goData))

        zmq_send(socket, goData, 0)
    }
}