利用protobuf和zmq实现网络通信

    xiaoxiao2023-09-26  149

    经过不短时间的调试,终于搞定了protobuf和zmq两个第三方库的编译和使用,并且参考往事前辈的代码编写了两者之间的通信demo。

    protobuf的编译和使用,前面有篇博客已经讲了。

    zmq的编译我用的是zeromq-4.2.3这个可以在vs2015下面编译通过。

    然后在zeromq-4.2.3_test\bin\Win32\Debug\v140\dynamic会生成lib和dll,dll每次用zmq的时候放到代码库,或者放到system32文件下面即可。

    完成了protobuf和zmq 的编译就可进行网络通信的代码编写了。

    我是参考别人的代码结构,但是我也踩了许多坑,调试成功的

    server端:

    #include #include"zmq.h" #include"zmq_utils.h" #include"helloworld.pb.h" const int bufflen = 128; using namespace std; int main() { void *context = zmq_ctx_new(); void responder = zmq_socket(context, ZMQ_REP); zmq_bind(responder, "tcp://:5555");

    while (1) { zmq_msg_t request; zmq_msg_init(&request); int size = zmq_msg_recv(&request, responder, 0); char buff[bufflen];//这个声明位置的不对会导致程序崩溃,原因见下面的分析。这个是C语言的特性。因为zmq内部实现为C语言。 memcpy(buff, zmq_msg_data(&request), size);

    helloworld rec; rec.ParseFromArray(buff, bufflen); cout << "id: " << rec.id() << "\t" << "str: " << rec.str() << "\n"; zmq_msg_close(&request); Sleep(200); memset(buff, 0,bufflen * sizeof(char)); helloworld msg; msg.set_id(303); msg.set_str("how"); msg.SerializeToArray(buff, bufflen); int len = strlen(buff); zmq_msg_t reply; zmq_msg_init_size(&reply, len); /* if (0 != zmq_msg_init_size(&reply, len)); { cout << "zmq_msg_init failed" << endl; break; } */ memcpy(zmq_msg_data(&reply), buff, len); zmq_msg_send(&reply, responder, 0); /* if (len = zmq_msg_send(&reply, responder, 0)) { zmq_msg_close(&reply); cout << "send failed..." << endl; break; } */ cout << "id: " << msg.id() << "\t" << "str: " << msg.str() << "\n"; zmq_msg_close(&reply);

    } zmq_close(&responder); zmq_ctx_destroy(context); system(“pause”); return 0; } 由于zmq的实现是C语言的,所以在变量声明中要注意声明的顺序。 最好用的时候再声明。解释是:编译器可能按声明变量顺序安排他们的位置,对字符串操作严重依赖在何处能找到字符串结束标志,如果没有,就用最近的’\0’,而它很可能是你上次赋值的其他变量的值的一部分。 客户端代码: #include #include"zmq.h" #include"zmq_utils.h" #include"helloworld.pb.h" using namespace std; const int bufflen = 128; int main() { void *context = zmq_ctx_new(); void *requester = zmq_socket(context, ZMQ_REQ); zmq_connect(requester, “tcp://127.0.0.1:5555”); cout << “Connect to server success…” << endl;

    while (1) { helloworld msg; msg.set_id(101); msg.set_str(“hello”);

    char buffer[bufflen]; msg.SerializeToArray(buffer, bufflen); int len = strlen(buffer); zmq_msg_t req; if (0 != zmq_msg_init_size(&req, len)) { cout << "zmq_msg_init failed..." << endl; break; } memcpy(zmq_msg_data(&req), buffer, len); if (len != zmq_msg_send(&req, requester, 0)) { zmq_msg_close(&req); cout << "send failed.." << endl; break; } cout << "id: " << msg.id() << "\t" << "str: " << msg.str() << "\n"; zmq_msg_close(&req); Sleep(200); memset(buffer, 0, bufflen * sizeof(char)); zmq_msg_t reply; zmq_msg_init(&reply); int size = zmq_msg_recv(&reply, requester, 0); memcpy(buffer, zmq_msg_data(&reply), size); helloworld rec; rec.ParseFromArray(buffer, bufflen); cout << "id: " << rec.id() << "\t" << "str: " << rec.str() << "\n"; zmq_msg_close(&reply);

    } zmq_close(&requester); zmq_ctx_destroy(context);

    system(“pause”); return 0; } 很好用啊。而且很强大。执行结果:

    最新回复(0)