I'm continuously sending arrays of pixel values (uint32) from LabVIEW to a C-program through TCP/IP. I'm using the recv function in Ws2_32.lib to receive the bytes, but I have to convert them back to uint32 data type and doesn't really know how to do it in this case. I'll be thankful if anyone shows how to do it.
Thanks in advance
#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;
}
Consider the following:
Output (My Machine is Little Endian):
If you capture 4
uint8_t
s at a time from the stream, you can convert them to anuint32_t
. Note that if your platform is little endian, you will have to do some byte rearranging.First ensure that your
do while
block works as expected.Concerning you question
As we know one dimensional array can be think as pointer to memory block. so
Also as array and pointer in our case can be used interchangeable We can access as indexed way too
As you see char will move one byte, but in our case we want to move 4 bytes. so we will make our pointer to point to int.
now we can access and fetch ints using the same syntax
And note that if
inarr
point to for example to address00004
,(inarr+1)
will point to00004+ 4=00008th
address. Cause pointer arithmetic will know that next int address will be obtained usingaddr+sizeof(int)
.Next issue. Bytes order can be different. see endianness On that case we have to make conversion. either we will write our functions. or we can use
htonl ntohl
. Or see this manual conversion endiannes conversion on stackoverflowThen coming to my code:
uint32_t *endp=(uint32_t*)(recvbuf+iResult);
will point to end of our array. so we will increment our pointer until it be equal to endp;while(p<endp) ++p;
and simple we will use*
dereference operator to get that value. after++p p
will point to next int block,and fetchinguint32_t
from that address will be equal to*p
. And we will increment that untilendp
Another option just to use index syntax. so we have to first calculate length of our array. How many ints we got in our array .this will be equal
iResult/sizeof(uint32_t)
iResult our length in bytes
. After that we can access index using*(p+index)
or more nice wayp[index]