изменение порядка следования байтов при передаче по Ethernet

Работаю с zedboard и vivado v2017.3. Я пытаюсь отправить данные, хранящиеся в регистре (slv_reg0 в разделе PL Zynq), указанном baseaddr_p в следующей программе.

Я использую приложение эхо-сервера lwip, чтобы прочитать этот адрес и отправить его на ПК через Ethernet.

Эта часть кода выполняется при получении эхо-запроса (telnet). В этой части кода я также печатаю прочитанные значения в gtkterm, чтобы я мог проверить полученные данные.

void process_echo_request(void *p)
{
    int sd = (int)p;
    int RECV_BUF_SIZE = 2048;
    char recv_buf[RECV_BUF_SIZE];
    int n,i,nwrote;
    unsigned long my_buffer[10];
    i=0;
    init_platform();
    while(1){
    while(i<11)
    {
    Xuint32 *baseaddr_p = (Xuint32 *)XPAR_MYIP_0_S00_AXI_BASEADDR;
    my_buffer[i] = *(baseaddr_p);
    xil_printf("0x%08x \n\r", my_buffer[i]);
    i++;}
    //xil_printf("0x%08x \n\r", my_buffer);
     /* handle request */
    if ((nwrote = write(sd, my_buffer, sizeof (my_buffer))) < 0) {
        xil_printf("%s: ERROR responding to client echo request. received = %d, written = %d\r\n",
                __FUNCTION__, n, nwrote);
        xil_printf("Closing socket %d\r\n", sd);
     break;

    }

    while (1) {
        /* read a max of RECV_BUF_SIZE bytes from socket */
        if ((n = read(sd, recv_buf, RECV_BUF_SIZE)) < 0) {
            xil_printf("%s: error reading from socket %d, closing socket\r\n", __FUNCTION__, sd);
            break;
        }

        /* break if the recved message = "quit" */
        if (!strncmp(recv_buf, "quit", 4))
            break;

        /* break if client closed connection */
        if (n <= 0)
            break;


        }
    }

    /* close connection */
    close(sd);
    vTaskDelete(NULL);
    cleanup_platform();
}

Результат gtkterm: прочитанные значения

При получении этих данных происходит перестановка байтов.

Полученные данные: 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00 09 00 00 00 0A 00 00 00 0B 00 00 00 0C 00 00 00 0D 00 00 00

Любое предложение о том, почему это происходит, и возможное обходное решение для этого?


person upasana    schedule 18.05.2018    source источник


Ответы (2)


Проблема связана с порядком байтов. Когда вы отправляете и получаете данные, всегда полезно выполнять преобразования хоста в сеть и наоборот.

Есть два POSIX API для преобразования порядка следования байтов: htonl и ntohl

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

person Vinay P    schedule 18.05.2018
comment
Большое спасибо. Теперь я получаю данные отлично. :D - person upasana; 18.05.2018

Ваша исходная машина использует внутреннее представление целых чисел с прямым порядком байтов. Его функция xil_printf() учитывает это для форматирования чисел каноническим способом для человеческого восприятия. Перестановка байтов существует, и она безобидна.

С другой стороны, write() не знает и не заботится о значении данных, которые вы ему передаете. Он обрабатывает все просто как последовательность байтов и передает их в том порядке, в котором они появляются. Точно так же функция read() получает и сохраняет байты в том порядке, в котором они приходят по сети. Никакого обмена байтами там не происходит.

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

Первый подход встречается гораздо чаще. На самом деле это роль функций htonl() и ntohl() определяется POSIX. Если у вас их нет, их не так уж сложно реализовать самостоятельно — самый большой трюк (и он не такой большой) — определить собственный порядок байтов.

person John Bollinger    schedule 18.05.2018
comment
Спасибо за объяснение. :D - person upasana; 18.05.2018