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