In our project, if we work on a 32 bit machine, we can represent an IP address as an `unsigned int' . But that would make our code non-portable to other machines, where an `unsigned int' might be 16 bits or 64 bits. Most (all?) operating systems provide datatypes specifically for use by TCP/IP and socket programming etc. In solaris (afs1 , ... , afs36) we can find these definitions in the file /usr/include/sys/int_types.h (If you want to use these: do NOT directly include this file. Study the issue first. Make sure you know what you are doing.) From that file: -------------------------------------- #if defined(_CHAR_IS_SIGNED) typedef char int8_t; #else #if defined(__STDC__) typedef signed char int8_t; #endif #endif typedef short int16_t; typedef int int32_t; #ifdef _LP64 typedef long int64_t; #else /* _ILP32 */ #if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG) typedef long long int64_t; #endif #endif typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; #ifdef _LP64 typedef unsigned long uint64_t; #else /* _ILP32 */ #if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG) typedef unsigned long long uint64_t; #endif #endif ---------------------------------------- so, int8_t , int16_t , int32_t , int64_t are ``signed integers'' of resp 8 , 16 , 32 , 64 bits long. uint8_t , uint16_t , uint32_t , uint64_t are ``unsigned integers'' of resp 8 , 16 , 32 , 64 bits long. Since I will run your code on one of afs1 , ... , afs36 (or on a similar other computer) and use the same OS, it is OK if you use an `unsigned int' to represent an address, and do a bitwise AND , and compare. Similarly, you can use an ``unsigned short'' for a port number. You might as well be sloppy and use an ``unsigned int'' or even an ``int'' (for port number). You will define your own classes. For example (from my program): class Address { public: unsigned int binaddr; // Address in binary form. // Does this require a 32 - bit machine? int decaddr[4]; // Address in ``numerical'' dotted decimal. Address(); // Constructor, initializes everything to zero. Address(int, int, int, int); // Takes 4 decimals. /* This is dangerous: will cause problems in ``real'' systems, if ``host byte order'' and ``network byte order'' are not the same! */ Address(int *); // Constructor, takes pointer to // array of 32 zero-ones. void printdecaddr(); // Print Dotted Decimal address as input. void printdecaddrshort(); // As above, without endl at end. void printbinaddr(); // Print ``binary'' address. }; Address::Address() { binaddr = 0; decaddr[0] = 0; decaddr[1] = 0; decaddr[2] = 0; decaddr[3] = 0; } Address::Address(int A1, int A2, int A3, int A4) { unsigned int mult[4] = {16777216, 65536, 256, 1}; // multipliers: 2^(24), 2^(16), 2^(8), 2^(0) . decaddr[0] = A1 ; decaddr[1] = A2 ; decaddr[2] = A3 ; decaddr[3] = A4 ; binaddr = decaddr[0]*mult[0] + decaddr[1]*mult[1] + decaddr[2]*mult[2] + decaddr[3]; } etc.