Отправка фрагментов данных через UDP - PullRequest
0 голосов
/ 03 ноября 2019

Я пытаюсь отправить порции данных (сейчас 1024 байта на пакет) через UDP, чтобы я мог получать данные в Matlab в режиме реального времени (или, по крайней мере, близко к реальному времени) с помощью DatagramReceivedFcn.

Поэтому я написал C-код, который выполняется на машине Linux для получения значений аналогового ввода (для целей тестирования я использовал целые числа) и попытался сделать так, чтобы код отправлял пакет, когда размер буфера достиг максимума в 1024 байта.

Мне также нужно добавить "!"как символ-терминатор для Matlab в конце буфера.

Но кажется, что размер буфера не всегда точно 1024 (иногда 1022, иногда больше), что вызывает у меня проблемы (странные знаки вместозначения) при получении данных в Matlab.

Не могли бы вы дать мне подсказку, что изменить в моем коде? Я очень новичок в программировании и особенно в программировании сокетов на C.

Заранее спасибо!

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <arpa/inet.h> 
#include <netinet/in.h> 
#include <time.h>
#include "/RedPitaya/api/include/redpitaya/rp.h"   //Header for RP API

#define MAXLINE 1024 
#define MAXBUFFSIZE 1024                //Definiert maximale Buffergroesse in Bytes - 8192 in MatLab Maximum

int main() { 
    int sockfd=0;
    char recv_buffer[MAXLINE];
    char send_buffer[MAXBUFFSIZE];          //Array als buffer
    struct sockaddr_in servaddr, cliaddr; 
    //float voltage;

    socklen_t len;

    // Initialization of RP-API
    if (rp_Init() != RP_OK) 
    {
        fprintf(stderr, "Red Pitaya API init failed!\n");
        return EXIT_FAILURE;
    }


    // Creating socket file descriptor 
    if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) 
    { 
        perror("socket creation failed"); 
        exit(EXIT_FAILURE); 
    } 

    memset(&servaddr, 0, sizeof(servaddr)); 
    memset(&cliaddr, 0, sizeof(cliaddr)); 

    // Filling server information 
    servaddr.sin_family    = AF_INET; // IPv4 
    servaddr.sin_addr.s_addr = INADDR_ANY; 
    servaddr.sin_port = htons(8080); 

    // Bind the socket with the server address 
    if ( bind(sockfd, (const struct sockaddr *)&servaddr,  
            sizeof(servaddr)) < 0 ) 
    { 
        perror("bind failed"); 
        exit(EXIT_FAILURE); 
    } 

    len = sizeof(cliaddr);
    int n;

    n = recvfrom(sockfd, (char *)recv_buffer, MAXLINE,  
                MSG_WAITALL, ( struct sockaddr *) &cliaddr, 
                &len); 
    recv_buffer[n] = '\0'; 
    printf("Client : %s", recv_buffer); 


int pck_counter = 0;
int i = 0;
int buffsize = 0;
int bytes_per_value = 0; 
int byteswritten;

while(pck_counter<10)               //counter ist Anzahl der Pakete - spaeter while(1)
{


    if((buffsize + bytes_per_value + strlen("!")) < MAXBUFFSIZE)
    {

        while((buffsize + bytes_per_value + strlen("!")) < MAXBUFFSIZE)     //https://stackoverflow.com/questions/37715229/c-sending-float-over-udp-results-in-random-symbols                   
        {
            //usleep(1);                                        //sleep 1ms

            //Get AI1-Value 
            //rp_AIpinGetValue(1, &voltage);                //Read Voltage of Pin1

            if(i==0)
            {
                bytes_per_value = sprintf(send_buffer,"%i %i;",pck_counter, i); //Konvertiert float zu string und schreibt in buffer - written = bytes die in Buffer geschrieben wurden

            }
            else
            {

                byteswritten = sprintf(send_buffer+strlen(send_buffer),"%i %i;",pck_counter, i); //Erhoeht Buffergroesse und fuegt neuen Wert hinzu //Funktioniert nicht wie es soll
                buffsize = (byteswritten*i)+bytes_per_value;
            }

            //printf("buffer: %s ", send_buffer); //printing value
            //printf("buffsize: %d ", buffsize);

            i++;

        }
    }

    else
    {

        // Add Terminator "!" 
        byteswritten = sprintf(send_buffer+strlen(send_buffer),"!");


        // Packet finished- Buffer full
        printf("Buffer %i full (%i) \n", pck_counter, buffsize);
        printf("buffer: %s ", send_buffer); //printing value

        if(sendto(sockfd, send_buffer, buffsize, 0,                 //Send data packet
                 (const struct sockaddr *) &cliaddr, 
                  len)<0)
        {
            perror("Sending failed");
        }
        else
        {
        //  printf("Data transmission for packet %i complete\n", pck_counter);
        }


        //Buffer leeren fuer naechsten Durchlauf
        fflush(stdin);
        buffsize = 0;
        i = 0;

        pck_counter++;

    }

}
    printf("All data transfered");
    return 0; 
} 


...