아래의 첫 번째 코드 조각 (GenericMessage.hxx에 정의 됨)에 표시된 GenericMessage라는 클래스가 있습니다.ZMQ : ZMQ 큐를 통해 사용자 지정 CPP 개체 보내기
ZMQ 대기열을 통해 GenericMessage 클래스의 인스턴스를 보내려고하는 TestFE.cpp 파일 (아래의 두 번째 코드 스 니펫 참조)이 있습니다 (아래의 네 번째 코드 스 니펫 - ZmqHandler.hxx 참고). TesfFE.cpp는 ZmqHandler.hxx를 포함하여 여기에 ZMQ 푸시 패턴을 구현합니다.
ZMQ 대기열을 통해 이렇게 언급 된 GenericMessage 인스턴스를받는 TestBE.cpp라는 파일 (아래의 세 번째 코드 스 니펫 참조)이 있습니다. TestBE.cpp는 ZMQ 큐를 통해 GenericMessage 인스턴스를 검색하기 위해 여기에 ZMQ 풀 패턴을 구현합니다.
TestFE.cpp에서 GenericMessage 객체를 ZMQ 대기열에서 수용 할 수있는 형식으로 변환하기 위해 표준 memcpy 함수를 사용합니다. TestBE.cpp (주석의 세 번째 코드 단편에 표시되어 있음)의 21 줄에서 memcpy가 TestFE.cpp 인 송신자 측에서 제대로 작동하지 않기 때문에 세그먼트 화 오류가 발생합니다. TestBE가 실행될 때 아래 메시지가 나타납니다. 나는 또한 바로 아래 gdb 백 트레이스를 제공하고있다. 여기서 뭐가 잘못 됐는지 말해 줄래? 왜 memcpy가 내 GenericMessage 객체를 ZMQ message_t 형식으로 제대로 복사 할 수 없다고 생각합니까? 아니면 다른 문제라고 생각합니까? 모든 의견을 주시면 감사하겠습니다.
오류 메시지
$ ./TestBE
Connecting to FE...
RECEIVED: 1
Segmentation fault (core dumped)
GDB 역 추적
(gdb) r
Starting program: /home/holb/HOLB_DESIGN/ZMQ/WORK1/TestBE
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
[New Thread 0xb7c84b40 (LWP 4252)]
[New Thread 0xb7483b40 (LWP 4253)]
Connecting to FE...
RECEIVED: 1
Program received signal SIGSEGV, Segmentation fault.
0xb7f371cc in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)()
from /usr/lib/i386-linux-gnu/libstdc++.so.6
(gdb) bt
#0 0xb7f371cc in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)()
from /usr/lib/i386-linux-gnu/libstdc++.so.6
#1 0x08049621 in GenericMessage<std::string>::getData (this=0xbffff06c)
at GenericMessage.hxx:18
#2 0x08049075 in main() at TestBE.cxx:21
(gdb)
1 코드 조각 (GenericMessage.hxx) #INCLUDE #INCLUDE #INCLUDE
,363,210template <class T>
class GenericMessage {
public:
GenericMessage(int id, T msg):
beId(id),
data(msg)
{}
~GenericMessage(){}
T getData()
{
//LINE 18 is the following line!
return data;
}
std::string toString()
{
std::ostringstream ss;
ss << getBeId();
std::string ret = ss.str();
return ret;
}
void setBeId(int id)
{
beId = id;
}
int getBeId()
{
return beId;
}
private:
int beId;
T data;
};
2 코드 조각 (TestFE.cxx ==> 발신자) 사용법 #include "ZmqHandler.hxx" 가 //
int main()
{
ZmqHandler<std::string> zmqHandler;
int counter = 1;
while(1)
{
std::string data = "Hello there!\0";
GenericMessage<std::string> msg(counter, data);
zmqHandler.sendToBE(&msg);
counter++;
sleep(1);
}
return 0;
}
ZmqHandler.hxx
의 내용에 대해서는 아래에서 4 니펫보기
코드 조각 3 (TestBE.cxx ==> 수신기)
#include "zmq.hpp"
#include "GenericMessage.hxx"
#include <string>
#include <iostream>
int main()
{
// Prepare our context and socket
zmq::context_t context (1);
zmq::socket_t socket (context, ZMQ_PULL);
std::cout << "Connecting to FE..." << std::endl;
socket.connect ("tcp://localhost:5555");
while(1){
zmq::message_t reply;
socket.recv (&reply);
GenericMessage<std::string> *msg = (GenericMessage<std::string>*)(reply.data());
std::cout << "RECEIVED: " << msg->toString() << std::endl;
/* ********************************* */
/* SEGMENTATION FAULT HAPPENS HERE */
/* The member "data" in class GenericMessage cannot be received while the member "id" in the previous line can be received. */
std::cout << "DATA: " << ((std::string)msg->getData()) << std::endl;
/* ********************************** */
}
return 0;
}
코드 조각 4 (ZMQHandler.hxx)
#include "zmq.hpp"
#include "GenericMessage.hxx"
#include <pthread.h>
#include <unistd.h>
#include <cassert>
template <class T>
class ZmqHandler {
public:
ZmqHandler():
mContext(1),
mOutbHandlerSocket(mContext, ZMQ_PUSH)
{
mOutbHandlerSocket.bind ("tcp://*:5555");
}
~ZmqHandler() {}
void *sendToBE(GenericMessage<T> *theMsg)
{
// Place the new request to the zmq queue for BE consumption
zmq::message_t msgToSend(sizeof(*theMsg));
memcpy (msgToSend.data(), ((GenericMessage<T>*)theMsg), sizeof(* ((GenericMessage<T>*)theMsg)));
mOutbHandlerSocket.send(msgToSend);
std::cout << "SENT request: [" << theMsg->toString() << "]" << std::endl;
return (NULL);
}
private:
zmq::context_t mContext;
zmq::socket_t mOutbHandlerSocket;
};
제목이 ZMQ 실패로 유감스럽게 생각합니다 ... 아마도 내 코드가 ZMQ에 실패했습니다.따라서 누군가가 기분을 상하게하는 경우 제목은 속임수가 아니며 미안합니다. –
GenericMessage.hxx 파일에서 18 번째 줄을 지적하면 도움이 될 것입니다. 게다가 GDB의'up' 명령을 사용하여 호출 스택을 올라갈 수 있습니다. 따라서 코드에 도달하면 변수를 검사하여 값을 확인할 수 있습니다. –
감사합니다. GenericMessage.hxx를 포함하여 첫 번째 코드 스 니펫에서 18 번째 줄을 가리키고 있습니다. –