在C中将字节转换为uint32

我不断通过TCP / IP将LabVIEW的像素值数组(uint32)发送到C程序。 我正在使用Ws2_32.lib中的recv函数来接收字节,但我必须将它们转换回uint32数据类型,并且在这种情况下并不真正知道如何操作。 如果有人知道如何做,我会感激不尽。

提前致谢

#define DEFAULT_BUFLEN 256 #include #include #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; } 

首先确保您的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); 

如您所见,char将移动一个字节,但在我们的情况下,我们想移动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地址。 原因指针算术将知道将使用addr+sizeof(int)获得下一个int地址。

下一期。 字节顺序可以不同。 看到endianness在这种情况下,我们必须进行转换。 要么我们要写我们的function。 或者我们可以使用htonl ntohl 。 或者在stackoverflow上查看此手动转换endiannes转换

然后来到我的代码: uint32_t *endp=(uint32_t*)(recvbuf+iResult); 将指向我们的数组的结尾。 所以我们将增加指针直到它等于endp; while(p 而且我们将使用* dereference运算符来获取该值。 在++pp将指向下一个int块,并从该地址获取uint32_t将等于*p 。 我们将增加直到endp

另一种选择就是使用索引语法。 所以我们必须先计算数组的长度。 我们在数组中得到了多少个。这将等于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 

考虑以下:

 #include  #include  #include  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 。 请注意,如果您的平台是小端,则必须进行一些字节重新排列。