2013-12-24 3 views
1

Я непрерывно отправляю массивы значений пикселей (uint32) из ​​LabVIEW в C-программу через TCP/IP. Я использую функцию recv в Ws2_32.lib для получения байтов, но мне нужно преобразовать их обратно в тип данных uint32 и на самом деле не знаю, как это сделать в этом случае. Я буду благодарен, если кто-нибудь покажет, как это сделать.Преобразование байтов в uint32 в C

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

#define DEFAULT_BUFLEN 256 

#include<stdio.h> 
#include<winsock2.h> 

#pragma comment(lib,"ws2_32.lib") //Winsock Library 

int main(int argc , char *argv[]) 
{ 
    WSADATA wsa; 
    SOCKET s , new_socket; 
    struct sockaddr_in server , client; 
    int c; 
    typedef unsigned char bytes[256]; 
    typedef unsigned int uint32_t; 
    int iResult; 
    char recvbuf[DEFAULT_BUFLEN]; 
    int recvbuflen = DEFAULT_BUFLEN; 




    printf("\nInitialising Winsock..."); 
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0) 
    { 
     printf("Failed. Error Code : %d",WSAGetLastError()); 
     return 1; 
    } 

    printf("Initialised.\n"); 

    //Create a socket 
    if((s = socket(AF_INET , SOCK_STREAM , 0)) == INVALID_SOCKET) 
    { 
     printf("Could not create socket : %d" , WSAGetLastError()); 
    } 

    printf("Socket created.\n"); 

    //Prepare the sockaddr_in structure 
    server.sin_family = AF_INET; 
    server.sin_addr.s_addr = INADDR_ANY; 
    server.sin_port = htons(13000); 

    //Bind 
    if(bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR) 
    { 
     printf("Bind failed with error code : %d" , WSAGetLastError()); 
    } 

    puts("Bind done"); 

    //Listen to incoming connections 
    listen(s , 3); 

    //Accept and incoming connection 
    puts("Waiting for incoming connections..."); 

    c = sizeof(struct sockaddr_in); 
    new_socket = accept(s , (struct sockaddr *)&client, &c); 
    if (new_socket == INVALID_SOCKET) 
    { 
     printf("accept failed with error code : %d" , WSAGetLastError()); 
    } 

    do {  
     iResult = recv(new_socket, recvbuf, recvbuflen, 0); 
     if (iResult > 0) 
      printf("%d\n", iResult); 
     else if (iResult == 0) 
      printf("Connection closed\n"); 
     else 
      printf("recv failed: %d\n", WSAGetLastError()); 

     } 
    while(iResult > 0); 

    closesocket(s); 
    WSACleanup(); 

    return 0; 
} 
+0

Поскольку вы не показываете/не описываете, как вы отправляете данные, советы о том, как их получить, - это только догадки. – alk

+0

Я отправляю данные как 2d массивы целых чисел uint32. Я сначала отправляю длину строки как 4 байта (тип I32 для строки). Затем отправляем строку после сглаживания из 2-мерного массива uint32. –

+0

Вам лучше показать код. – alk

ответ

1

Сначала убедитесь, что ваш do while блок работает, как ожидалось.

Что касается вас вопрос

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

char *ar = recvbuf ; 

char x1= *ar; //will get first byte (index 0) 
char x2=*(ar+1); //will get second byte (index 1) 

Кроме того, как массив и указатель в нашем случае можно использовать взаимозаменяемые Мы можем получить доступ, как индексный путь слишком

char x1=ar[0];// the same as *ar 
    char x2=ar[1]; //= *(ar+1); 

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

int *intarr=(int *) recvbuf ; //recvbuf is address 

теперь мы можем получить доступ и получать Интс, используя тот же синтаксис

int x1=*intarr; 
    int x2= *(intarr+1); // *((int*)(ar+4)) 
//or 
    int x1=intarr[0]; 

И заметьте, что если inarr пункт, например, для решения 00004, (inarr+1) будет указывать на 00004+ 4=00008th адрес. Арифметика указателя причины будет знать, что следующий int-адрес будет получен с использованием addr+sizeof(int).

Следующий выпуск. Порядок байтов может быть другим. см. endianness В этом случае мы должны сделать преобразование. либо мы напишем наши функции. или мы можем использовать htonl ntohl. Или см. Это ручное преобразование endiannes conversion on stackoverflow

Затем, доходя до моего кода: uint32_t *endp=(uint32_t*)(recvbuf+iResult); укажет на конец нашего массива. поэтому мы будем увеличивать указатель до тех пор, пока он не будет равен endp; while(p<endp) ++p; и просто мы будем использовать оператор разыменования *, чтобы получить это значение. после ++p p будет указывать на следующий int-блок, и выборка uint32_t с этого адреса будет равна *p. И мы увеличим это до endp

Еще один вариант использования синтаксиса индекса. поэтому мы должны сначала вычислить длину нашего массива. Сколько ints мы получили в нашем массиве. Это будет равно iResult/sizeof(uint32_t)iResult our length in bytes.После того, что мы можем получить доступ к индексу с помощью *(p+index) или более приятный способ p[index]

... 

uint32_t *p=(uint32_t*)recvbuf; 
uint32_t *endp=(uint32_t*)(recvbuf+iResult); 



//here is accessing 
while(p<endp){ 
    //ntohl(*p) if it was send from begin endian 
    uint32_t value=*p;p++; 
} 

//or 
uint32_t *p=(uint32_t*)recvbuf; 
size_t len=iResult/sizeof(uint32_t); 
// 
for(int i=0;i<len;i++){ 
    uint32_t value= p[i]; //and again if there is endian problem solve it using ntonl htonl 

} 
+0

Привет. Не могли бы вы объяснить код в словах? –

+0

@ пользователь2292615 смотрите, если это полезно – qwr

1

Рассмотрим следующий пример:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(void) 
{ 
    uint8_t char byteArray[4] = {0xBE, 0xEF, 0xFA, 0xCE}; 
    uint32_t int32Word = *(uint32_t *)byteArray; 

    printf("%#X\n", int32Word); 

#ifdef LITTLE_ENDIAN 
    int32Word = ((int32Word & 0xFF000000) >> 24) | 
       ((int32Word & 0x00FF0000) >> 8) | 
       ((int32Word & 0x0000FF00) << 8) | 
       ((int32Word & 0x000000FF) << 24); 

    printf("%#X\n", int32Word); 
#endif 

    system("pause"); 
    return 0; 
} 

выход (моя машина Little Endian):

0xCEFAEFBE
0xBEEFFACE
Нажмите любую клавишу, чтобы продолжить. , ,

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

Смежные вопросы