2016-07-22 3 views
0

ZeroMQ 소켓을 사용하여 데이터를 전송하고 멀티 파트 메시지를 게시 할 장치 용 데이터 레코딩 시스템을 작성하고 있습니다.ZeroMQ를 사용하여 C로 멀티 파트 메시지 받기

내 프로그램은 정상적으로 정확히 작동하는 파이썬 스크립트를 작성 C.

로 작성하는 내가 관리 할 않았다해야합니다. 이는 다음과 같습니다

import zmq 
import time 
import numpy as np 

_HEARTBEAT_PREFIX =  b'ray.heartbeat\0' 
_RAW_DATA_PREFIX =  b'ray.rawdata\0' 

context = zmq.Context.instance() 

time.sleep(5) 

socket = context.socket(zmq.SUB) 
socket.setsockopt(zmq.LINGER, 0) 
socket.setsockopt(zmq.SUBSCRIBE, b'') 
time.sleep(5) 
socket.connect("tcp://localhost:50290") 
time.sleep(5) 
go = True 
while go: 

    if socket.poll(1000): 

     zframes = socket.recv_multipart(flags=zmq.NOBLOCK, copy=False) 

     if (zframes[0].buffer.tobytes() == _HEARTBEAT_PREFIX): 
      print ('Heartbeart') 
     elif (zframes[0].buffer.tobytes() == _RAW_DATA_PREFIX): 
      dataToWrite = np.frombuffer(zframes[1].buffer, dtype='i2') 
      print ('Raw data: ') 
      # and so on ... 

이 내가 C이 파이썬 코드는 진정한 도전입니다 ZMQ와 협력 포트에 노력하고 이번이 처음이다. 내가 실행 이제 작성한 있지만 제대로 작동하지 않는 C 코드 :

#include "zhelpers.h" 

int main (int argc, char *argv []) 
{ 

    void *context = zmq_ctx_new(); 
    void *subscriber = zmq_socket(context,ZMQ_SUB); 

    int rc = zmq_connect(subscriber,"tcp://localhost:50290"); 
    assert(rc == 0); 
    rc = zmq_setsockopt(subscriber,ZMQ_SUBSCRIBE, "", 0); 
    assert(rc == 0); 

    while (1) 
    { 
    zmq_msg_t message; 
    zmq_msg_init (&message); 
    zmq_msg_recv (&message, subscriber,0);//, ZMQ_NOBLOCK); 
    // Process the message frame 


    int size = zmq_msg_size(&message); 
    char *string = malloc(size + 1); 
    memcpy(string, zmq_msg_data(&message), size); 


    zmq_msg_close (&message); 

    string[size] = 0; 
    printf("Message[%d]: %s\n", size, string); 

    if (!zmq_msg_more (&message)) 
     break;  // Last message frame 
    } 
    return 0; 
} 

이 코드는 그러나 수신 데이터의 정확한 크기를 제공하지만 데이터를 표시 할 때 너무 읽을 수없는 문자 (기호와 표시 on) .. 파이썬에서와 마찬가지로 들어오는 데이터를 더 처리하기 위해 문자열로 가져와야합니다.

+0

C 코드가 프레임 유형 (하트 비트/원시 데이터)을 확인하지 않는 것 같습니다. 첫 번째 프레임이 유형 인 것 같고 유형이 원시 데이터 인 경우 다음 프레임에는 인쇄 할 수있는 내용이 들어 있습니다. –

답변

0

파이썬에서 numpy 배열이 int를 포함하는 문자열 배열로 변환되고 C 프로그램에서 해석하기에 매우 어려운 값을 발견했습니다. 나는 올바른 값을 추출 할 수 있었다 수신 된 데이터를 조작하여

: 이것은 단지 파이썬에서 NumPy와 배열을 수신에 문제가 있음을

#include "zhelpers.h" 

int main (int argc, char *argv []) 
{ 

    int i = 0; 

    void *context = zmq_ctx_new(); 
    void *subscriber = zmq_socket(context,ZMQ_SUB); 

    int rc = zmq_connect(subscriber,"tcp://localhost:50290"); 
    assert(rc == 0); 

    char* filter = "ray."; 

    rc = zmq_setsockopt(subscriber,ZMQ_SUBSCRIBE, filter, sizeof(filter)); 
    assert(rc == 0); 
    int nextFrame = 0; 

    while (1) 
    { 

    zmq_msg_t message; 
    zmq_msg_init (&message); 
    zmq_msg_recv (&message, subscriber,0);//, ZMQ_NOBLOCK); 

    // Process the message frame 

    int size = zmq_msg_size(&message); 
    char *string = malloc(size + 1); 
    memcpy(string, zmq_msg_data(&message), size); 

    if (nextFrame) 
    { 

     zmq_msg_close (&message); 
     printf("Raw data: "); 
     string[size] = 0; 
     //printf("Data: %s\n", string); 
     for (i = 0; i < size; i+=2) 
     { 

     printf("%d ", (int16_t) ((string[i] & 0xff) +((string[i+1] & 0xff)<<8))); 

     } 


    } 
     if (strcmp(string, "ray.rawdata") != 0) 
     { 
     nextFrame = 0; 
     break; 
     } 
     else 
     { 
     nextFrame = 1; 

     zmq_msg_close (&message); 

     string[size] = 0; 
     printf("Prefix: %s\n", string); 

     if (!zmq_msg_more (&message)) 
      break;  // Last message frame 
     } 

    }} 
    return 0; 
} 

주 - 한이 하트 비트 문자열 또는 무엇으로, 문제 없습니다.