2016-07-22 24 views
0

Ich schreibe ein Datenaufzeichnungssystem für ein Gerät, das Daten mit dem ZeroMQ-Socket übertragen und mehrteilige Nachrichten veröffentlichen wird.Empfangen von mehrteiligen Nachrichten in C mit ZeroMQ

Mein Programm muss in C.

geschrieben werden ich ein Python-Skripte schreiben, habe es geschafft, die genau funktioniert, wie es sollte. Das sieht wie folgt aus:

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 ... 

Dies ist das erste Mal, dass ich mit ZMQ arbeite und zu versuchen, zu portieren diese Python-Code zu C ist eine echte Herausforderung. Der C-Code, den ich jetzt geschrieben wird laufen, aber funktioniert nicht richtig:

#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; 
} 

Dieser Code wird die richtige Größe der eingehenden Daten jedoch liefern, aber wenn die Anzeige der Daten zeigt sie als lesbare Zeichen (Symbole und so on ..) Ich werde, wie ich es in Python mache, die eingehenden Daten als String bekommen, um sie weiter zu verarbeiten.

+0

Der C-Code scheint den Rahmentyp (Heartbeat/Rohdaten) nicht zu überprüfen. Der erste Rahmen scheint der Typ zu sein, und wenn der Typ Rohdaten ist, enthält der nächste Rahmen etwas, das möglicherweise druckbar ist. –

Antwort

0

Ich fand heraus, dass das numpy-Array in Python in ein String-Array konvertiert wurde, das int enthält, und sie waren sehr schwierige Werte für das C-Programm zu interpretieren.

durch die empfangenen Daten zu manipulieren konnte ich die richtigen Werte extrahieren:

#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; 
} 

Beachten Sie, dass dies nur ein Problem ist, wenn numpy Arrays von Python Empfang - solange es sich um ein Herzschlag-String oder was auch immer ist, da sind keine Probleme.