ntp - Is there a simpler way to take a substring of an char array and convert it to a long in C? -
i looking shorter/more elegant way ntp timestamp received ntp packet. packet stored in unsigned char array, buf, socket function recvfrom:
unsigned char buf[48]; recvfrom(sockfd, buf, 48, 0, (struct sockaddr *) &their_addr, &addr_len));
i copying value of 40th-43rd elements represent 32-bit timestamp of seconds unsigned long, transsec, bitshifting so:
recvpacket->transmitsec = buf[40]; recvpacket->transsec <<= 8; recvpacket->transsec |= buf[41]; recvpacket->transsec <<= 8; recvpacket->transsec |= buf[42]; recvpacket->transsec <<= 8; recvpacket->transsec |= buf[43];
this works fine, in interest of learning, there shorter/more elegant way of doing this? have tried memcpy:
memcpy(&recvpacket->transsec, &buf[40], sizeof(unsigned long));
and other variations of above, getting incorrect numbers. not particularly confident i'm using correctly.
what might endianness issue. check wiki entry here: http://en.wikipedia.org/wiki/endianness. in short, byte ordering of type isn't same 1 system another. looks you're doing network communication - check out byte order conversion family functions:
http://beej.us/guide/bgnet/output/html/multipage/htonsman.html
note buf[40] first byte stream, , being shifted way highest byte of underlying type. memcpy on other hand, copy buf[40] 0-offset of transsec - byte order reversed in 2 examples.
you can check out in code this, you'll declare character pointer ( character being smallest addressable type in c) , walk length of size of type address you're inspecting, address+sizeof(type):
// declare char * char * walker; // set integer walker = (char *)&(recvpacket->transsec); ( = 0; < sizeof(unsigned long); i++){ // print out bytes memory address[0] - address[3] ( assuming 4-byte unsigned long) printf("%x\n", walker[i]); }
you can walk buff too, that's char buffer so, might print it. think you'll see byte order reversed.
Comments
Post a Comment