Rectangle 27 2

Use htonl() to convert a 32-bit integer from host byte order to network byte order before sending it, and use ntohl() to convert a 32-bit integer from network byte order to host byte order after receiving it. There are also htons() and ntohs() for 16-bit integers. Let the functions decide how to convert the values for you. On little endian systems, the functions are implemented to perform actual conversions. On big endian systems, the functions are implemented as no-ops.

I'm sending the byte stream as little endian from LabVIEW. So I also have to switch to litte-endian in this code, right ?

Network byte order is big endian. If LabVIEW is sending the data in little endian instead, and your app is running on a little endian system, then it does not need to do anything special, the data is already in the correct endian. But if LabVIEW is sending in little endian and your app is running on a big endian system, then you need to convert the values. Your code operates in whatever endian the CPU natively uses, so you have to be aware of endian issues whenever your app's data interacts with outside systems.

c - Little-endian byte order - Stack Overflow

c sockets tcp endianness
Rectangle 27 4

In your question, you stated that you want to convert a user input of 175 to 00000000 00000000 00000000 10101111, which is big endian byte ordering, also known as network byte order.

A mostly portable way to convert your unsigned integer to a big endian unsigned char array, as you suggested from that "175" example you gave, would be to use C's htonl() function (defined in the header <arpa/inet.h> on Linux systems) to convert your unsigned int to big endian byte order, then use memcpy() (defined in the header <string.h> for C, <cstring> for C++) to copy the bytes into your char (or unsigned char) array.

The htonl() function takes in an unsigned 32-bit integer as an argument (in contrast to htons(), which takes in an unsigned 16-bit integer) and converts it to network byte order from the host byte order (hence the acronym, Host TO Network Long, versus Host TO Network Short for htons), returning the result as an unsigned 32-bit integer. The purpose of this family of functions is to ensure that all network communications occur in big endian byte order, so that all machines can communicate with each other over a socket without byte order issues. (As an aside, for big-endian machines, the htonl(), htons(), ntohl() and ntohs() functions are generally compiled to just be a 'no op', because the bytes do not need to be flipped around before they are sent over or received from a socket since they're already in the proper byte order)

#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>

int main() {
    unsigned int number = 175;

    unsigned int number2 = htonl(number);
    char numberStr[4];
    memcpy(numberStr, &number2, 4);

    printf("%x %x %x %x\n", numberStr[0], numberStr[1], numberStr[2], numberStr[3]);

    return 0;
}

Note that, as caf said, you have to print the characters as unsigned characters using printf's %x format specifier.

The above code prints 0 0 0 af on my machine (an x86_64 machine, which uses little endian byte ordering), which is hex for 175.

Converting an int into a 4 byte char array (C) - Stack Overflow

c
Rectangle 27 1

Use the family of macros/functions http://linux.die.net/man/3/ntohs to send data over the network. Then you will not have any problems at all.

c - Little-endian byte order - Stack Overflow

c sockets tcp endianness
Rectangle 27 3

The sizeof an empty class or structure is 1

The reason this happens boils down to properly implementing the standard, one of the things the C++ standard says is that "no object shall have the same address in memory as any other variable".... What is the easiest way to ensure this? Make sure that all types have a non-zero size. In order to achieve this the compiler adds a dummy byte to structures and classes that have no data members and no virtual functions so that they have a size of 1 rather than a size of 0 and then they are guaranteed to have a unique memory address.

C++: What is the size of an object of an empty class? - Stack Overflow

c++ class object
Rectangle 27 3

The sizeof an empty class or structure is 1

The reason this happens boils down to properly implementing the standard, one of the things the C++ standard says is that "no object shall have the same address in memory as any other variable".... What is the easiest way to ensure this? Make sure that all types have a non-zero size. In order to achieve this the compiler adds a dummy byte to structures and classes that have no data members and no virtual functions so that they have a size of 1 rather than a size of 0 and then they are guaranteed to have a unique memory address.

C++: What is the size of an object of an empty class? - Stack Overflow

c++ class object
Rectangle 27 0

Use htonl() to convert a 32-bit integer from host byte order to network byte order before sending it, and use ntohl() to convert a 32-bit integer from network byte order to host byte order after receiving it. There are also htons() and ntohs() for 16-bit integers. Let the functions decide how to convert the values for you. On little endian systems, the functions are implemented to perform actual conversions. On big endian systems, the functions are implemented as no-ops.

I'm sending the byte stream as little endian from LabVIEW. So I also have to switch to litte-endian in this code, right ?

Network byte order is big endian. If LabVIEW is sending the data in little endian instead, and your app is running on a little endian system, then it does not need to do anything special, the data is already in the correct endian. But if LabVIEW is sending in little endian and your app is running on a big endian system, then you need to convert the values. Your code operates in whatever endian the CPU natively uses, so you have to be aware of endian issues whenever your app's data interacts with outside systems.

c - Little-endian byte order - Stack Overflow

c sockets tcp endianness
Rectangle 27 0

Use the network byte order (big endian), which is the same as Java uses anyway. See man htons for the different translators in C.

I'm not at my linux box now but is htons one of the standard libs?

htons is available almost everywhere, but it's not in ISO C.

If you have to use something other than network byte order, then you either roll your own with bitwise operators or use the various versions of java.nio.Buffer

According to its man-page it's defined in POSIX.1, so it should be available pretty much everywhere. And I seem to remember using it in Win32, so it's not just on POSIX systems either.

endianness - Are Integers in Java little endian or big endian? - Stack...

java endianness
Rectangle 27 0

This is because %d expects a pointer to a 4-byte integer, and you are passing a pointer to a 1-byte char. Because variables a, b and c are stored in the order of decreasing memory addresses, sscanf first fills a with 23, at the same time filling 3 other bytes of stack memory with zeros (this is a memory violation, BTW). Then it fills b with 13, also filling a and two other bytes with zeros. In the end it fills c with 45, also filling a and b and one other byte with zeros. This way you end up with zeros in both b and a, and an expected value only in c.

Of course this is only one possible scenario of what can happen, as it depends on the architecture and compiler.

A proper way to read 4 integers would be to use int instead of unsigned char, or change the format specifier.

c - Separated integers with comma delimiters and sscanf - Stack Overfl...

c comma sscanf separator
Rectangle 27 0

+ (NSString*) unescapeUnicodeString:(NSString*)string
{
// unescape quotes and backwards slash
NSString* unescapedString = [string stringByReplacingOccurrencesOfString:@"\\\"" withString:@"\""];
unescapedString = [unescapedString stringByReplacingOccurrencesOfString:@"\\\\" withString:@"\\"];

// tokenize based on unicode escape char
NSMutableString* tokenizedString = [NSMutableString string];
NSScanner* scanner = [NSScanner scannerWithString:unescapedString];
while ([scanner isAtEnd] == NO)
{
    // read up to the first unicode marker
    // if a string has been scanned, it's a token
    // and should be appended to the tokenized string
    NSString* token = @"";
    [scanner scanUpToString:@"\\u" intoString:&token];
    if (token != nil && token.length > 0)
    {
        [tokenizedString appendString:token];
        continue;
    }

    // skip two characters to get past the marker
    // check if the range of unicode characters is
    // beyond the end of the string (could be malformed)
    // and if it is, move the scanner to the end
    // and skip this token
    NSUInteger location = [scanner scanLocation];
    NSInteger extra = scanner.string.length - location - 4 - 2;
    if (extra < 0)
    {
        NSRange range = {location, -extra};
        [tokenizedString appendString:[scanner.string substringWithRange:range]];
        [scanner setScanLocation:location - extra];
        continue;
    }

    // move the location pas the unicode marker
    // then read in the next 4 characters
    location += 2;
    NSRange range = {location, 4};
    token = [scanner.string substringWithRange:range];
    unichar codeValue = (unichar) strtol([token UTF8String], NULL, 16);
    [tokenizedString appendString:[NSString stringWithFormat:@"%C", codeValue]];

    // move the scanner past the 4 characters
    // then keep scanning
    location += 4;
    [scanner setScanLocation:location];
}

// done
return tokenizedString;
}

+ (NSString*) escapeUnicodeString:(NSString*)string
{
// lastly escaped quotes and back slash
// note that the backslash has to be escaped before the quote
// otherwise it will end up with an extra backslash
NSString* escapedString = [string stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"];
escapedString = [escapedString stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];

// convert to encoded unicode
// do this by getting the data for the string
// in UTF16 little endian (for network byte order)
NSData* data = [escapedString dataUsingEncoding:NSUTF16LittleEndianStringEncoding allowLossyConversion:YES];
size_t bytesRead = 0;
const char* bytes = data.bytes;
NSMutableString* encodedString = [NSMutableString string];

// loop through the byte array
// read two bytes at a time, if the bytes
// are above a certain value they are unicode
// otherwise the bytes are ASCII characters
// the %C format will write the character value of bytes
while (bytesRead < data.length)
{
    uint16_t code = *((uint16_t*) &bytes[bytesRead]);
    if (code > 0x007E)
    {
        [encodedString appendFormat:@"\\u%04X", code];
    }
    else
    {
        [encodedString appendFormat:@"%C", code];
    }
    bytesRead += sizeof(uint16_t);
}

// done
return encodedString;
}

it must be legal to kill server-side developer, just for forcing me to use this solution. @Christoph nice working code by the way. Cheers!

Using Objective C/Cocoa to unescape unicode characters, ie \u1234 - St...

objective-c cocoa unicode
Rectangle 27 0

What kind of network? IP is defined in terms of bytes so whatever order the bit stream happens to be in the underlying layers has been abstracted away from you and you receive the bits in the order that your CPU understands them. Which means that the abstraction that C provides you to access those bits is portable. Think in terms of shifting left or right in C. Whatever the endianness is in the CPU the direction and semantics of shifting in C doesn't change.

So the question is: how is the data encoded into a byte stream by the other end? However the other end encodes the data should be the way you decode it. If they just shove bits into one byte and send that byte over the network, then you don't need to care. If they put bits into one int16 and then send it in network byte order, then you need to worry endianness of that int16. If they put the bits into an int32 and send that, then you need to worry about endianness of that int32.

c - Does endianess matter when reading N bits from unsigned char - Sta...

c endianness
Rectangle 27 0

This is how I solved it coming from being a c programmer to a c# programmer. I like to use MemoryStream to convert it to a stream and then BinaryReader to break apart the binary block of data. Had to add the two helper functions to convert from network order to little endian. Also for building a byte[] to send see http://stackoverflow.com/questions/360111 which has a function that allow for converting from an array of objects to a byte[].

Hashtable parse(byte[] buf, int offset )
  {

     Hashtable tcpheader = new Hashtable();

     if(buf.Length < (20+offset)) return tcpheader;

     System.IO.MemoryStream stm = new System.IO.MemoryStream( buf, offset, buf.Length-offset );
     System.IO.BinaryReader rdr = new System.IO.BinaryReader( stm );

     tcpheader["SourcePort"]    = ReadUInt16BigEndian(rdr);
     tcpheader["DestPort"]      = ReadUInt16BigEndian(rdr);
     tcpheader["SeqNum"]        = ReadUInt32BigEndian(rdr);
     tcpheader["AckNum"]        = ReadUInt32BigEndian(rdr);
     tcpheader["Offset"]        = rdr.ReadByte() >> 4;
     tcpheader["Flags"]         = rdr.ReadByte() & 0x3f;
     tcpheader["Window"]        = ReadUInt16BigEndian(rdr);
     tcpheader["Checksum"]      = ReadUInt16BigEndian(rdr);
     tcpheader["UrgentPointer"] = ReadUInt16BigEndian(rdr);

     // ignoring tcp options in header might be dangerous

     return tcpheader;
  } 

  UInt16 ReadUInt16BigEndian(BinaryReader rdr)
  {
     UInt16 res = (UInt16)(rdr.ReadByte());
     res <<= 8;
     res |= rdr.ReadByte();
     return(res);
  }

  UInt32 ReadUInt32BigEndian(BinaryReader rdr)
  {
     UInt32 res = (UInt32)(rdr.ReadByte());
     res <<= 8;
     res |= rdr.ReadByte();
     res <<= 8;
     res |= rdr.ReadByte();
     res <<= 8;
     res |= rdr.ReadByte();
     return(res);
  }

That is certainly a simple, elegant way to do it. I've defined classes for the IP, TCP, and UDP headers. Internally, I use the BitConverter functions to extract the values and IPAddress.NetworkToHostOrder to swap the bytes. I may run some tests to see which approach is more efficient.

you might want to look at stackoverflow.com/questions/2871 if performance is what you are after and switch from classes to structs. I would also leave everything in network order and only convert when you need it.

.net - Working with byte arrays in C# - Stack Overflow

c# .net networking .net-3.5 bytearray
Rectangle 27 0

Generally, you need to worry about endianness (byte-order) when you transfer integers larger than a single byte from one computer to another. In C/C++, this means that if you're sending something like a 16-bit, 32-bit or 64-bit integer, you need to first convert the integer to network byte order, (also known as Big-Endian). The computer on the receiving end must then convert the incoming integers to host byte order, which is whatever byte-order the host-machine uses natively. This is usually done using the htons and ntohs series of library functions, but with the Qt library you can also use the qToBigEndian and qFromBigEndian functions.

Note that you don't need to worry about endianness when sending ASCII or UTF-8 text, because these formats are composed of sequences of individual bytes, rather than multi-byte data types.

It's not always necessary or sensible to do this, if you were streaming video it wouldn't make sense to convert every byte to htons and then back again - it would be better to have a code so the receiving machine knew which way round the data was.

Wrong, UTF-8 is variable-width encoding, guaranteed to represent every unicode character and can thus take up to 4 bytes.

No, your understanding is incorrect. UTF-8 is variable width encoding, but it is not affected by endianness because the variable-length characters are composed of ordered byte sequences, unlike UTF-16 or UTF-32 where the smallest unit is a 2 (or 4) byte binary integer whose byte-order is determined by architecture endianness.

c++ - Qt Sockets and Endianness - Stack Overflow

c++ qt sockets networking endianness
Rectangle 27 0

If a C (or other language) standard declares that some particular code will have Undefined Behavior in some situation, that means that a C compiler can generate code to do whatever it wants in that situation, while remaining compliant with that standard. Many particular language implementations have documented behaviors which go beyond what is required by the generic language standard. For example, Whizbang Compilers Inc. might explicitly specify that its particular implementation of memcpy will always copy individual bytes in address order. On such a compiler, code like:

would have behavior which was defined by the Whizbang documentation, even though the behavior of such code is not specified by any non-vendor-specific C language specification. Such code would be compatible with compilers that comply with Whizbang's spec, but could be incompatible with other compilers which comply with various C standards but do not comply with Whizbang's specifications.

There are many situations, especially with embedded systems, where programs will need to do some things which the C standards do not require compilers to allow. It is not possible to write such programs to be compatible with all standards-compliant compilers, since some standards-compliant compilers may not provide any way to do what needs to be done, and even those that do might require different syntax. Nonetheless, there is often considerable value in writing code that will be run correctly by any standards-compliant compiler.

c - On Undefined Behavior - Stack Overflow

c undefined-behavior
Rectangle 27 0

Crazy idea: just write a C99 or C++03 -conforming program in the first...

I would suggest not using vendor-specific C language extensions to match device or network bit formats. Even if you get the fields to line up using a series of one-per-vendor language extensions, you still have byte order to worry about, and you still have a struct layout that requires extra instructions to access.

You can write a C99 conforming program that will work on any architecture or host and at maximum speed and cache efficiency by using the standardized C API string and memory copy functions and the Posix hton and ntoh functions.

A good practice is to use the following functions for which there exist published standards:

C99: memcpy(), Posix: htonl(), htons(), ntohl(), ntohs()

Update: here is some code that should work the same everywhere. You may need to get <stdint.h> from this project if Microsoft still hasn't implemented it for C99, or just make the usual assumptions about int sizes.

#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <arpa/inet.h>

struct packed_with_bit_fields {  // ONLY FOR COMPARISON
    unsigned int   a    	: 3;
    unsigned int   b    	: 1;
    unsigned int   c    	: 15;
    unsigned int   troubleMaker : 16;
    unsigned short padding  : 13;
} __attribute__((packed));       // USED ONLY TO COMPARE IMPLEMENTATIONS

struct unpacked { // THIS IS THE EXAMPLE STRUCT
    uint32_t a;
    uint32_t b;
    uint32_t c;
    uint32_t troubleMaker;
}; // NOTE NOT PACKED

struct unpacked su;
struct packed_with_bit_fields sp;
char *bits = "Lorem ipsum dolor";

int main(int ac, char **av) {
  uint32_t x;   // byte order issues ignored in both cases

  // This should work with any environment and compiler
  memcpy(&x, bits, 4);
  su.a = x & 7;
  su.b = x >> 3 & 1;
  su.c = x >> 4 & 0x7fff;
  memcpy(&x, bits + 2, 4);
  su.troubleMaker = x >> 3 & 0xffff;

  // This section works only with gcc
  memcpy(&sp, bits, 6);
  printf( sp.a == su.a
      &&  sp.b == su.b
      &&  sp.c == su.c
      &&  sp.troubleMaker == su.troubleMaker
      ? "conforming and gcc implementations match\n" : "huh?\n");
  return 0;
}

Given that it's tagged as C++, writing a C++03-conforming program might be a better idea. ;)

Heh, good point, but it's also tagged gcc, it's using C89 code, and if MS actually had a C compiler it's possible that would be the real target. :-)

They have a C89 compiler.

The reason I am even trying to do it this way is I am using legacy code that someone else wrote. We've been lucky up to this point but some new messages have been causing this problem. I was pretty sure it needed to be rethought but I wanted to see if anyone had any useful input on how to make it work as it is...

Sure, systems work is usually legacy code, I have sympathy. I just wrote the headline that way to scare any new guys that read it into writing conforming code for the next poor guy to come along and maintain. :-)

memory - C++ struct alignment question - Stack Overflow

c++ memory gcc visual-c++
Rectangle 27 0

Even byteorder is abstracted by the NIC/Network stack in the kernel. It is translated for you. When programming sockets in C, you do sometimes have to deal with byte ordering for the network when sending data ... but that doesn't concern 32 or 64 bit differences.

When dealing with blobs of binary data, mapping them from one architecture to another (as an overlay to a C struct for example) can cause problems as others have mentioned, but this is why we develop architecture independent protocols based on characters and so on.

In-fact things like Java run in a virtual machine that abstracts the machine another step!

Knowing a bit about the instruction set of the architecture, and how the syntax is compiled to that can help you understand the platform and write cleaner, tighter code. I know I grimace at some old C code after studying compilers!

Been blissfully unaware of processor hardware for years and years. Haven't known or needed to know since I last wrote real-time controllers for military weapons.

java - Would one have to know the machine architecture to write code? ...

java c++ python 64bit 32-bit
Rectangle 27 0

You can use the standard network bytswapping functions in apa/inet.h:

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong); // Host to network
uint16_t htons(uint16_t hostshort); // Host to network
uint32_t ntohl(uint32_t netlong); // Network to host
uint16_t ntohs(uint16_t netshort); // Network to host
hton*: Host endian to big endian
ntoh*: Big endian to host endian

c - Supporting byte ordering in Linux user space - Stack Overflow

c linux endianness
Rectangle 27 0

The bytes in a frame are in a fixed order (big-endian as @Caleb points out), independent of endianness of the host computer.

Since you're copying the bytes one-by-one this will always work. There's only a problem when you would use multi-byte assignments or memcpy's from the frame data into short, int, .... Have a look at ntohs() and friends that convert network-to-host and vice versa.

c - Network byte order on MAC address - Stack Overflow

c sockets networking mac-address
Rectangle 27 0

The standard notation, also called canonical format, for MAC addresses is written in transmission bit order with the least significant bit transmitted first.

IEEE 802.3 (Ethernet) and IEEE 802.4 (Token Bus) send the bytes (octets) over the wire, left-to-right, with least significant bit in each byte first, while IEEE 802.5 (Token Ring) and IEEE 802.6 send the bytes over the wire with the most significant bit first

An address in canonical form 12-34-56-78-9A-BC would be transmitted over the wire as bits 10000100 00101100 01101010 00011110 01011001 00111101 in the standard transmission order (least significant bit first).

But for Token Ring networks, it would be transmitted as bits 00010010 00110100 01010110 01111000 10011010 10111100 in most-significant-bit first order. The latter might be incorrectly displayed as 48-2C-6A-1E-59-3D. This is referred to as bit-reversed order, non-canonical form, MSB format, IBM format, or Token Ring format. Canonical form is generally preferred, and used by all modern implementations.

c - Network byte order on MAC address - Stack Overflow

c sockets networking mac-address
Rectangle 27 0

Data elements (e.g. members of classes and structs) are typically aligned on WORD or DWORD boundaries for current generation processors in order to improve access times. Retrieving a DWORD at an address which isn't divisible by 4 requires at least one extra CPU cycle on a 32 bit processor. So, if you have e.g. three char members char a, b, c;, they actually tend to take 6 or 12 bytes of storage.

#pragma allows you to override this to achieve more efficient space usage, at the expense of access speed, or for consistency of stored data between different compiler targets. I had a lot of fun with this transitioning from 16 bit to 32 bit code; I expect porting to 64 bit code will cause the same kinds of headaches for some code.

Actually, char a,b,c; will usually take either 3 or 4 bytes of storage (on x86 at least) -- that's because their alignment requirement is 1 byte. If it weren't, then how would you deal with char str[] = "foo";? Access to a char is always a simple fetch-shift-mask, while access to an int can be fetch-fetch-merge or just fetch, depending on whether it's aligned or not. int has (on x86) a 32-bit (4 byte) alignment because otherwise you'd get (say) half an int in one DWORD and half in the other, and that would take two lookups.

c++ - #pragma pack effect - Stack Overflow

c++ c preprocessor
Rectangle 27 0

* This code will query a ntp server for the local time and display
 * it.  it is intended to show how to use a NTP server as a time
 * source for a simple network connected device.
 * This is the C version.  The orignal was in Perl
 *
 * For better clock management see the offical NTP info at:
 * http://www.eecis.udel.edu/~ntp/
 *
 * written by Tim Hogard (thogard@abnormal.com)
 * Thu Sep 26 13:35:41 EAST 2002
 * Converted to C Fri Feb 21 21:42:49 EAST 2003
 * this code is in the public domain.
 * it can be found here http://www.abnormal.com/~thogard/ntp/
 *
 */
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <time.h>
#include <string.h>

void ntpdate();

int main() {
    ntpdate();
    return 0;
}

void ntpdate() {
char    *hostname="tick.usno.navy.mil";
int portno=123;     //NTP is port 123
int maxlen=1024;        //check our buffers
int i;          // misc var i
unsigned char msg[48]={010,0,0,0,0,0,0,0,0};    // the packet we send
unsigned long  buf[maxlen]; // the buffer we get back
//struct in_addr ipaddr;        //  
struct protoent *proto;     //
struct sockaddr_in server_addr;
int s;  // socket
int tmit;   // the time -- This is a time_t sort of

//use Socket;
//
//#we use the system call to open a UDP socket
//socket(SOCKET, PF_INET, SOCK_DGRAM, getprotobyname("udp")) or die "socket: $!";
proto=getprotobyname("udp");
s=socket(PF_INET, SOCK_DGRAM, proto->p_proto);
if(s) {
    perror("asd");
    printf("socket=%d\n",s);
}
//
//#convert hostname to ipaddress if needed
//$ipaddr   = inet_aton($HOSTNAME);
memset( &server_addr, 0, sizeof( server_addr ));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr = inet_addr(hostname);
//argv[1] );
//i   = inet_aton(hostname,&server_addr.sin_addr);
server_addr.sin_port=htons(portno);
//printf("ipaddr (in hex): %x\n",server_addr.sin_addr);

/*
 * build a message.  Our message is all zeros except for a one in the
 * protocol version field
 * msg[] in binary is 00 001 000 00000000 
 * it should be a total of 48 bytes long
*/

// send the data
printf("sending data..\n");
i=sendto(s,msg,sizeof(msg),0,(struct sockaddr *)&server_addr,sizeof(server_addr));

// get the data back
i=recv(s,buf,sizeof(buf),0);
printf("recvfr: %d\n",i);
//perror("recvfr:");

//We get 12 long words back in Network order
/*
for(i=0;i<12;i++)
    printf("%d\t%-8x\n",i,ntohl(buf[i]));
*/

/*
 * The high word of transmit time is the 10th word we get back
 * tmit is the time in seconds not accounting for network delays which
 * should be way less than a second if this is a local NTP server
 */

tmit=ntohl((time_t)buf[10]);    //# get transmit time
//printf("tmit=%d\n",tmit);

/*
 * Convert time to unix standard time NTP is number of seconds since 0000
 * UT on 1 January 1900 unix time is seconds since 0000 UT on 1 January
 * 1970 There has been a trend to add a 2 leap seconds every 3 years.
 * Leap seconds are only an issue the last second of the month in June and
 * December if you don't try to set the clock then it can be ignored but
 * this is importaint to people who coordinate times with GPS clock sources.
 */

tmit-= 2208988800U; 
//printf("tmit=%d\n",tmit);
/* use unix library function to show me the local time (it takes care
 * of timezone issues for both north and south of the equator and places
 * that do Summer time/ Daylight savings time.
 */


//#compare to system time
printf("Time: %s",ctime(&tmit));
i=time(0);
//printf("%d-%d=%d\n",i,tmit,i-tmit);
printf("System time is %d seconds off\n",i-tmit);
}

sntp client in c++ for time/date - Stack Overflow

c++ c ntp