Получение бинарных данных через сокет в C ++

0

У меня есть блок MCU, подключенный к локальной сети. Это устройство отправляет данные статуса через сокет TCP 100 раз в секунду. В том же сокете я могу также выдавать команды и данные.

Я пытаюсь написать простой TCP-клиент, который мог бы подключиться к устройству, захватить данные и запросить команды отправки. В настоящее время я могу отправлять команды без проблем (команды отправляются как строки, и это работает). Моя проблема - прием данных из устройства FROM.

Я знаю из руководства по эксплуатации, что сначала данные должны быть 32-битными целыми числами, а затем массивом примерно 30 удвоений)

Я устанавливаю новый поток, который я хочу последовательно перехватить данные и обработать их:

void *com::setListenerSocket(void* threadSocketData) {
        struct socketData *sockData;
        sockData = (socketData*)threadSocketData;
        com::tcp_client cListener;

        struct timeval timeout;
        timeout.tv_sec=0;
        timeout.tv_usec=12500;

    //  setsockopt(cListener, IPPROTO_TCP, SO_RCVTIMEO, (char *)timeout, sizeof(timeout)); //no effect
        cListener.connect(sockData->host , sockData->port);
        cout << "listener thread started" << endl;
        cout << "host=" << sockData->host << " at port=" << sockData->port << endl;

        cListener.send_data("Listener Reporting\n");
    while(listenerRun){
        listenerHB++;
        cout << endl <<"*****************************       BGN     *************************************************************"<< endl;
        char *received = new char[PACKETSIZE];
        cListener.receive(PACKETSIZE, received);
        unsigned int test;
        test = (uint32_t) received;
        cout << "received=" << test << endl;
        for(int i = 0; i< PACKETSIZE ; ++i)
          cout << received[i] << ", ";
        cout << endl <<"*****************************       END     *********************************************"<< endl;
        robotPacket data;
        //parseData(received, &data);
        //usleep(1 MS);
    }
    cout << "listener signing out" << endl;;
    pthread_exit(NULL);
}

и метод слушателя:

void com::tcp_client::receive(int size, char* buffer) {

  unsigned int bytecnt = 0, archive = 1;

  while(bytecnt < (unsigned int)size) {
//     bytecnt += recv(sock , &buffer[bytecnt] , size-bytecnt , 0); 
    bytecnt += recv(sock , buffer , size-bytecnt , MSG_WAITALL); 
  }

  unsigned int test;
  test = buffer[0];
  cout << "value=" << test << "¤" << endl;
  }

Я взял указатель на начало буфера и отбросил его на uint32_t, но результат полностью ошибочен (я знаю, что это должна быть длина пакета, но она легко распространяется на миллионы миллионов)

Когда я использую команду nl: nc -l 12354 Я могу написать текст в свою программу, и все правильно

EDIT: Встреча с кем-то более опытным: РЕШЕННО: я не могу опубликовать решение самостоятельно, поэтому я поставлю его здесь, если кто-то столкнется с аналогичной проблемой.

Прежде всего, я ожидал, что сокет будет автоматически обрабатываться там, где начинается одна передача, а где его конец - что не так, как указал Базиль Старинкевич. Тем не менее, TCP гарантирует, что данные будут поступать последовательно, и ничего не потеряно, поэтому я могу с уверенностью предположить, что за 500 байтов, обещанных, я получу 500 байтов или что бы это ни было.

Во-вторых, данные поступают в большой эндиант - также, как указал Базиль. Я немного перепутал, но все же имел неправильный результат, но...

Наконец, у меня была другая проблема с типом. Я использовал char *, в то время как данные являются символами unsigned. Замена буферов char * с unsigned char * решила проблему декодирования.

Это может быть решением для всех, кто получает интерфейс со старыми электронными разработчиками, которые общаются по локальной сети.

Думаю, этот случай можно считать закрытым, если кто-то пишет то, что я написал выше, в аккуратной форме.

  • 0
    recv может потерпеть неудачу с отрицательным bytecnt
  • 0
    if (probe = recv (sock, buffer, size-bytecnt, MSG_WAITALL)> 0) bytecnt + = probe; Теперь данные поступают намного медленнее, но первое целое число все еще безумно ... Что может вызвать отрицательный результат bytecnt?
Показать ещё 4 комментария
Теги:
sockets
binary

1 ответ

0

Вы можете проверить tcpclient (http://cr.yp.to/ucspi-tcp/tcpclient.html). Вы можете просто запустить свою программу C/C++ под tcpclient - т.е. Tcpclient вызовет вашу программу и откроет tcp-соединение с сервером, а также передаст вашу программу stdout на сервер и выведет на сервер вывод на вашу программу stdin. Самое приятное в том, что вы делаете это так, что вы можете позволить tcpclient для всех тяжелых подъемов до установки сокета и т.д., И вы можете сосредоточиться на основной функции вашей программы.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню