C and C++
NOTE: This page is still being constructed; please check back frequently for updates.
This page contains basic beginner and more advanced C and C++ snippets. The purpose of this page is two fold; a reference for those who are learning (and like to learn via pure code), as well as, a location for mpettersson to keep snippets and C/C++ related links. This pages subsections are:
C/C++ 101
The following are the general and technical aspects of the C and C++ programming languages:
C | C++ | |
---|---|---|
Uses: | Application, System, Low-Level | Application, System |
Website: | gcc.gnu.org | isocpp.org |
Get Started: | gcc.gnu.org | Get Started! |
Download: | gcc.gnu.org/install | gcc.gnu.org |
Documents: | ISO/IEC 9899:2018 | isocpp.org |
Creator: | Dennis Ritchie | Bjarne Stroustrup |
First Released: | 1972 | 1985 |
Implementation: | Compiled | Compiled |
Type Safety: | Weak | Weak |
Type System: | Explicit | Explicit with optional Implicit (in/after C++11) |
Type Checking: | Static | Static |
Imperative: | Yes | Yes |
Aspect Oriented: | No | No |
Object Oriented: | No | Yes |
Functional: | No | Yes |
Procedural: | Yes | Yes |
Generic: | Yes | Yes |
Reflective: | No | Yes |
Event Driven: | No | Yes |
Standardized: | Yes (ISO C18) | Yes (ISOCPP) |
Failsafe I/O: | No | Some (STL iostreams do, but C APIs like stdio do not) |
Garbage Collected: | No (can be added through Boehm GC library) | No (can be added through Boehm GC library) |
C/C++ Concepts and Definitions
Pointer
– A pointer VARIABLE can store a memory address (Unlike normal variable which stores a value, such as an int).
– A VARIABLE that stores the address of another VARIABLE.
– A void pointer is a type of pointer that can point to somewhere without a specific type.
– A NULL pointer is a value that any pointer can take to represent that it is pointing to “nowhere”
& (Address of Operator)
– The address of a variable can be obtained by preceding the name of a variable with an ampersand sign (&).
– For example: “foo = &myvar;” This would assign the address (not value) of myvar to foo;
* (Dereference Operator) (indirection operator)
– Operates on a pointer, and returns the value stored in the address kept in the pointer variable.
– Can be read as “value pointed to by”
References (&)
– When a variable is declared as reference, it becomes an alternative name for an existing variable.
– A variable can be declared as reference by putting ‘&’ in the declaration.
– A reference must be initialized when declared.
– Once a reference is created, it cannot be it cannot be reassigned (pointers can be reassigned).
– References cannot be NULL (pointers are often made NULL).
– Example: “int x = 10; int& ref = x;” now you can use x or ref interchangeably, without use of the dereference op.
– For common uses see: https://www.geeksforgeeks.org/references-in-c/
namespace
– Namespaces allow for a named scope (of types, functions, variables, etc.).
– Namespace is a feature added in C++ and not present in C.
– Multiple namespace blocks with the same name are allowed.
– A namespace definition begins with the keyword “namespace” followed by the namespace name and a {}
– Namespace declarations appear only at global scope.
– Namespace declarations can be nested within another namespace.
– Namespace declarations don’t have access specifiers. (Public or private)
– No need to give semicolon after the closing brace of definition of namespace.
– Example: “namespace namespace_name {int x, y;}” now you can access elsewhere with namespace_name::x
– Example: “#include <iostream>; using namespace std;” will let us do “cout << …” as opposed to “std::cout << …”
– NOTE: It’s not recommended to use “using namespace std;”.
Types
– Primitive Data Types:
– Are built-in or predefined data types and can be used directly to declare variables.
– Include: int, char, bool, float, double, void, wchar_t
– Derived Data Types:
– Are derived from the primitive or built-in datatypes.
– Namely: Function, Array, Pointer, Reference
– Abstract or User-Defined Data Types:
– These data types are defined by user.
– User-defined datatypes include: Class, Structure, Union, Enumeration, Typedef defined DataType
– Data type modifiers available in C++ are: signed, unsigned, short, long
volatile
– The volatile keyword informs the compiler that the value of variable it is applied to can change from the outside, without any update done by the code. This may be done by the OS, the hardware, or another thread.
– The compiler will load the value from memory each time.
– Volatile variables are not optimized.
– Volatile var are useful when multi-threaded programs have global var and any thread can modify shared vars.
Constructor
– A member function of a class which initializes an object of the class.
– A constructor is different from normal functions in following ways:
– Constructors has same name as the class itself
– Constructors do NOT have a return type
– A constructor is automatically called when an object is created.
– If no constructor is specified, the C++ compiler generates a default constructor (no args w/ empty body).
Destructor (~)
– A member function which destructs or deletes an object.
– A destructor function is called automatically when the object goes out of scope:
(1) the function ends
(2) the program ends
(3) a block containing local variables ends
(4) a delete operator is called
– Destructors have same name as the class preceded by a tilde (~)
– Destructors don’t take any argument and don’t return anything
– There can only one destructor in a class with classname preceded by ~, no parameters and no return type.
– When do we need to write a user-defined destructor?
– If we do not write our own destructor in class, compiler creates a default destructor for us.
– The default destructor works fine unless we have dynamically allocated memory or pointer in class.
– When a class contains a pointer to memory allocated in class, we should write a destructor to release memory
before the class instance is destroyed. This must be done to avoid memory leak.
– Destructors can be virtual (and should be virtual in base class with virtual function(s))
Structures (struct)
– Are user defined data types which are used to store group of items of non-similar data types.
– Example: “struct Point { int x, y; };” … “struct Point p1” use p1.x to access x (use pointer->x if pointer).
typedef
– Is used to assign a new name to any existing data-type.
– Example: “typedef unsigned int uint;” … “uint i = 5;”
– NOTE: typedef is used a lot with templates.
Declarations
– A declaration introduces a name into a scope.
– Example: “extern int y;” declares y, but does not define it (y is defined elsewhere)
Prototype
– A declaration for a function.
– Example: “double someFunction( double, int );”
Definition
– A definition fully specifies an entity.
– Definitions are where the actual creation of the entity in memory takes place.
– All definitions are also declarations, but not all declarations are definitions.
– Example: “int x;” declares and defines x; it is a definition because it creates the variable allocating memory
Implementations
– An implementation is another name for a definition of a function.
– That is, the implementation is the actual code of the function itself.
Preprocessor Directives
– Tell the compiler to preprocess (do something to) the source code before compiling.
– All preprocessor directives begin with a ‘#’ (hash) symbol (i.e., #include, #define, #ifndef)
– The (‘#’) symbol at the beginning of a statement indicates that it is a pre-processor directive.
– Preprocessor directives can be anywhere in a program.
– There are 4 main types of preprocessor directives:
– Macros (with and without arguments) – start with #define
– File Inclusion – start with #include
– Conditional Compilation – start with #ifdef macro_name and ends with #endif
– Other directives: #undef to undefine an existing macro and #pragma to turn on/off features
:: (scope resolution operator) is used to:
1) To access a global variable when there is a local variable with same name: I.E., ::var
2) To define a function (for a class) outside the class.
3) To access a class’s static variables from outside the class.
4) In case of multiple Inheritance (to access a classes variables).
5) For namespace I.E., std::cout
6) Refer to a class inside another class: I.E., outsideClass::insideClass::someVar = 7
Templates
– A way of reusing code to apply the same class to different data types (similar to Generics in Java).
Header Files
– The files that tell the compiler how to call some functionality (without knowing how the functionality actually works) are called header files.
– They contain the function prototypes.
– They also contain Data types and constants used with the libraries.
– We use #include to use these header files in programs. These files end with .h extension.
Library
– Library is the place where the actual functionality is implemented i.e. they contain function body.
– Libraries have mainly two categories: Static and Dynamic
Static Library
– Contains object code linked with an end user application and then they become the part of the executable.
– These libraries are specifically used at compile time which means the library should be present in correct location when user wants to compile his/her C or C++ program.
– In windows they end with .lib extension and with .a for MacOS.
Shared Library or Dynamic Library
– These libraries are only required at run-time i.e, user can compile his/her code without using these libraries.
– In short these libraries are linked against at compile time to resolve undefined references and then its distributed to the application so that application can load it at run time.
– For example, when we open our game folders we can find many .dll(dynamic link libraries) files. As these
libraries can be shared by multiple programs, they are also called as shared libraries.
– These files end with .dll or .lib extensions. In windows they end with .dll extension.
Virtual (base) classes
– Are used in virtual inheritance in a way of preventing multiple “instances” of a given class appearing in an
inheritance hierarchy when using multiple inheritances.
Virtual function
– A member function which is declared within a base class and is re-defined(Overriden) by a derived class.
– When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class’s version of the function.
– Virtual functions ensure that the correct function is called for an object, regardless of the type of reference (or pointer) used for function call.
– They are mainly used to achieve Runtime polymorphism
– Functions are declared with a virtual keyword in base class.
– The resolving of function call is done at Run-time.
– Virtual functions cannot be static and also cannot be a friend function of another class.
– Should be accessed using pointer or reference of base class type to achieve run time polymorphism.
– The prototype of virtual functions should be same in base as well as derived class.
– They are always defined in base class and overridden in derived class.
– It is not mandatory for derived class to override (or re-define the virtual function),
in that case base class version of function is used.
– A class may have virtual destructor but it cannot have a virtual constructor.
Pure Virtual Function (abstract function)
– A virtual function that doesn’t have an implementation (only method signature is declared).
– A pure virtual function is declared by assigning 0 in declaration.
– Example: virtual void show() = 0;
Abstract Class
– A class that contains at least one Pure Virtual Function
Operator Overloading
– The ability to provide the operators with a special meaning for a custom data type.
– The overloading function is always “operator” keyword followed by symbol of operator (i.e., “+”) and operator
functions are called when the corresponding operator is used.
– Almost all operators can be overloaded, the EXCEPTIONS are: . (dot) :: ?: sizeof
Default (Method) Values
– Methods/Functions can specify default values (like python)
– All default values must be after (right of) all non-default parameters.
– Example: “int func(int a, int b = 3){ … }”
? : (Ternary Operator) (same as Java)
C Keywords
auto | break | case | char | const | continue |
default | do | double | else | enum | extern |
float | for | goto | if | int | long |
register | return | short | signed | sizeof | static |
struct | switch | typedef | union | unsigned | void |
volatile | while |
C++14 Keywords
alignas | alignof | asm | auto | bool | break |
case | catch | char | char16_t | char32_t | class |
const | constexpr | const_cast | continue | decltype | default |
delete | do | double | dynamic_cast | else | enum |
explicit | export | extern | false | float | for |
friend | goto | if | inline | int | long |
mutable | namespace | new | noexcept | nullptr | operator |
private | protected | public | register | reinterpret_cast | return |
short | signed | sizeof | static | static_assert | static_cast |
struct | switch | template | this | thread_local | throw |
true | try | typedef | typeid | typename | union |
unsigned | using | virtual | void | volatile | wchar_t |
while |
C/C++ Syntax
NOTE: This page is still being developed…
If you’re using a Mac or other Unix based machine, you’re probably able to execute C and C++ code. For C/C++ on Windows you have several C compiler and C++ compiler options… In case you were wondering, yes, Eclipse and NetBeans have support for C/C++.
The following is basic C and C++ syntax.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// A Single Line Comment /* A Multi Line, Or Block Comment */ char my_char; // (x86) 1byte, signed: -128 to 127, unsigned: 0 to 255 short int my_short; // (x86) 2byte, signed: -32768 to 32767, unsigned: 0 to 65535 int my_int; // (x86) 4byte, signed: -2147483648 to 2147483647, unsigned: 0 to 4294967295 long int my_long_int; // (x86) 4byte, signed: -2147483648 to 2147483647, unsigned: 0 to 4294967295 bool my_boolean; // (x86) 1byte, true or false float my_float; // (x86) 4byte, +/- 3.4e +/- 38 (~7 digits) double my_double; // (x86) 8byte, +/- 1.7e +/- 308 (~15 digits) long double my_long_double; // (x86) 8byte, +/- 1.7e +/- 308 (~15 digits) wchar_t my_wide_character; // (x86) 2 or 4bytes, 1 wide character string my_string = "This is my string."; |
Pointers
The following is a short set of pointer notes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
// DECLARATION int *p1, *p2, i; // p1 and p2 are int pointers. i is an int int number = 88; // An int variable with a value int * pNumber; // Declare a pointer variable called pNumber pointing to an int (or int pointer) // DEFINITION pNumber = &number; // Assign the address of the variable number to pointer pNumber int * pAnother = &number; // Declare another int pointer and init to address of the variable number p1 = pNumber // Assign address in pointer pNumber to pointer p1. // ARRAYS & POINTERS int myarray [20]; // Arrays work like pointers to their first elements. int * mypointer; // Only real diff between arrays and pointers is arrays can't be reassigned. mypointer = myarray; // This works/is valid (notice no &) myarray = mypointer; // Wouldn't work. a[5] = 0; // a [offset of 5] = 0 A CAN BE A POINTER OR AN ARRAY is equivalent to *(a+5) = 0 *(a+5) = 0; // pointed to by (a+5) = 0 A CAN BE A POINTER OR AN ARRAY is equivalent to a[5] = 0 // POINTER ARITHMETICS (only addition and subtraction operations are allowed) char *mychar; // REMEMBER, incrementing or decrementing a pointer will change the address value long *mylong; // in accordance to the type it is. ++mychar; // Pointer address will increase by the size of a char (much less than a long) ++mylong; // Pointer address will increase by the size of a long (much more than a char) *p++ // same as *(p++): increment pointer, and dereference unincremented address *++p // same as *(++p): increment pointer, and dereference incremented address ++*p // same as ++(*p): dereference pointer, and increment the value it points to (*p)++ // dereference pointer, and post-increment the value it points to *p++ = *q++; // Same as: *p = *q; ++p; ++q; // CONST & POINTERS int x; int y = 10; const int * p = &y; // const-qualified can READ but NOT MODIFY a pointed value (p CAN --/++ or be reassigned) int const * p = &x; // SAME const-qualified Syntax (READ, but cant MODIFY, CAN ++/--, be reassigned) x = *p; // ok: reading p *p = x; // error: modifying p, which is const-qualified void func(const int* pI) // NOTE: Const pointers are commonly used in functions to prevent changing arguments. int * p1 = &x; // non-const pointer to non-const int const int * p2 = &x; // non-const pointer to const int (CAN READ AND BE CHANGED (++/--), CANNOT WRITE) int * const p3 = &x; // const pointer to non-const int (CAN READ AND WRITE, CANNOT BE CHANGED (++/--)) const int * const p4 = &x; // const pointer to const int (CAN READ, CANNOT WRITE OR BE CHANGED (++/--)) // POINTERS TO POINTERS char a; // Pointers can point to data, or even to other pointers. char * b; // SYNTAX: Add asterisk (*) for each level of indirection in the dec of the pointer: char ** c; // NOTE: a = 'z'; // c is of type char** and a value of b = &a; // *c is of type char* and a value of &a c = &b; // **c is of type char and a value of 'z' // MISC POINTERS void * data; // VOID POINTERS point values that have no type (undetermined length/dereferencing properties). int * p; // UNINITIALIZED POINTER int myarray[10]; int * q = myarray+20; // ELEMENT OUT OF BOUNDS POINTER int * p = 0; // NULL POINTER or a pointer explicitly pointing to nowhere. int * q = nullptr; // NULL POINTER. All null pointers compare equal to other null pointers. int * r = NULL; // NULL POINTER int (* pF)(int,int) = sub // FUNCTION POINTER named pF, with 2 int args, initialized to point to the function sub |
Miscellaneous C/C++ Code
This section will contain a mix of interesting, helpful, and otherwise slightly more advanced snippets.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <iostream> #define MY_PORT 12346 /* arbitrary, but client and server must agree */ #define BUF_SIZE 4096 #define MAX_PENDING 5 using namespace std; int main(int argc, char **argv) { int sockfd; /* socket listening for incoming connections */ int newsockfd; /* socket created for sending and receiving data */ struct sockaddr_in servaddr, cliaddr; socklen_t addrlen; int datalen; char mesg[BUF_SIZE]; /* * Open a TCP socket (an Internet stream socket). */ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { cerr << "server: can't open stream socket"; exit(1); } /* * Fill in the structure "servaddr" with the local address and port. * INADDR_ANY automatically fills in the local host's IP address. */ servaddr.sin_family = AF_INET; servaddr.sin_port = htons(MY_PORT); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* * Bind our local address so that the client can send to us. */ if (bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) { cerr << "server: can't bind local address"; exit(1); } /* * Listen for incoming connection. */ listen(sockfd, MAX_PENDING); /* * Accept an incoming connection, receive data, echo data back to * sender, close socket, repeat. */ for( ; ; ) { addrlen = sizeof(cliaddr); if ((newsockfd = accept(sockfd, (struct sockaddr *)&cliaddr, &addrlen)) < 0) { cerr << "server: can't accept connection"; exit(1); } while (datalen = recv(newsockfd, mesg, BUF_SIZE, 0)) { send(newsockfd, mesg, datalen, 0); } close(newsockfd); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
//#include <stdio.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <iostream> #define MY_PORT 12346 /* arbitrary, but client and server must agree */ #define BUF_SIZE 4096 #define MAX_PENDING 5 using namespace std; int main(int argc, char **argv) { fd_set master; /* master file descriptor list */ fd_set read_fds; /* temp file descriptor list for select () */ int fdmax; /* maximum file descriptor numer */ FD_ZERO(&master); /* clear master and temp sets */ FD_ZERO(&read_fds); int listensockfd; /* socket listening for incoming connections */ int newsockfd; /* socket created for sending and receiving data */ struct sockaddr_in servaddr, cliaddr; socklen_t addrlen; int datalen; char mesg[BUF_SIZE+1]; int i,j; /* * Open a TCP socket (an Internet stream socket). */ if ((listensockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { cerr << "server: can't open stream socket"; exit(1); } cout << "server: listen socket created with socketfd: " << listensockfd << endl; /* * Fill in the structure "servaddr" with the local address and port. * INADDR_ANY automatically fills in the local host's IP address. */ bzero(&servaddr, sizeof(servaddr)); /* set everything to zero */ servaddr.sin_family = AF_INET; servaddr.sin_port = htons(MY_PORT); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* * Bind our local address to the socket so that the client can send to us. */ if (bind(listensockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) { cerr << "server: can't bind local address"; exit(1); } /* * Listen for incoming connection. */ listen(listensockfd, MAX_PENDING); /* * Add listensockfd to master list for select. Keep track of * biggest file descriptor so far. */ FD_SET(listensockfd, &master); fdmax = listensockfd; // this is the only fd so far /* * Accept an incoming connection, receive data, echo data back to * sender, close socket, repeat. */ for( ; ; ) { read_fds = master; /* need to make a copy because select will update it upon return */ cout << endl; cout << "server: fds monitored: "; /* Print out which fds are being monitored */ for (i = 0; i<= fdmax; i++) { cout << FD_ISSET(i,&read_fds) << " "; } cout << endl; if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { cerr << "server: select error"; exit(1); } /* * When select returns, read_fds will be updated with the list of ready descriptors. * Go through read_fds to see which has data ready. */ cout << "server: fds ready for read: "; /* Print out which fds have data to be read */ for (i = 0; i<= fdmax; i++) { cout << FD_ISSET(i,&read_fds) << " "; } cout << endl; for (i = 0; i<= fdmax; i++) { if (FD_ISSET(i, &read_fds)) { /* Found a ready descriptor */ if (i == listensockfd) { /* If it is the listening socket, accept connection */ addrlen = sizeof cliaddr; if ((newsockfd = accept(listensockfd, (struct sockaddr *)&cliaddr, &addrlen)) < 0) { cerr << "server: can't accept connection"; } else { FD_SET(newsockfd, &master); /* Add new socket descriptor to master list */ if (newsockfd > fdmax) { fdmax = newsockfd; } cout << "server: new connection from " << inet_ntoa(cliaddr.sin_addr) << " on socketfd " << newsockfd << endl; } } else { /* It is a socket with data ready to be read */ if ((datalen = recv(i, mesg, BUF_SIZE, 0)) <= 0) { if (datalen == 0) { /* Connection closed by client */ cout << "server: socket " << i << " hung up" << endl; } else { cerr << "server: recv"; } close(i); /* Hang up */ FD_CLR(i, &master); /* Remove descriptor from master set */ } else { /* Got some data from client */ cout << "server: data from socketfd " << i << endl; send(i, mesg, datalen, 0); /* Echo it back to user */ } } } } } close(newsockfd); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <iostream> #define MY_PORT 12346 /* arbitrary, but client and server must agree */ #define BUF_SIZE 4096 #define MAX_PENDING 5 using namespace std; int main(int argc, char **argv) { int sockfd; /* socket listening for incoming connections */ int newsockfd; /* socket created for sending and receiving data */ struct sockaddr_in servaddr, cliaddr; socklen_t addrlen; int datalen; char mesg[BUF_SIZE]; /* * Open a TCP socket (an Internet stream socket). */ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { cerr << "server: can't open stream socket"; exit(1); } /* * Fill in the structure "servaddr" with the local address and port. * INADDR_ANY automatically fills in the local host's IP address. */ servaddr.sin_family = AF_INET; servaddr.sin_port = htons(MY_PORT); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* * Bind our local address so that the client can send to us. */ if (bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) { cerr << "server: can't bind local address"; exit(1); } /* * Listen for incoming connection. */ listen(sockfd, MAX_PENDING); /* * Accept an incoming connection, receive data, echo data back to * sender, close socket, repeat. */ for( ; ; ) { addrlen = sizeof(cliaddr); if ((newsockfd = accept(sockfd, (struct sockaddr *)&cliaddr, &addrlen)) < 0) { cerr << "server: can't accept connection"; exit(1); } while (datalen = recv(newsockfd, mesg, BUF_SIZE, 0)) { send(newsockfd, mesg, datalen, 0); } close(newsockfd); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <iostream> #define DEST_PORT 12346 /* arbitrary, but client and server must agree */ #define BUF_SIZE 4096 using namespace std; int main(int argc, char **argv) { int sockfd; struct sockaddr_in servaddr; struct hostent *h_server; /* Read command line inputs. Get server host name and IP address. * The function gethostbyname() will return a structure containing * the IP address for the given host name. */ if (argc !=2) { cout << "Usage: client server-name" << endl; exit(1); } if ((h_server = gethostbyname(argv[1])) == NULL) { cerr << "client: can't get server address" << endl; exit(1); } /* * Fill in the structure "serv_addr" with the address and the * port of the server that we want to connect with. */ servaddr.sin_family = AF_INET; servaddr.sin_port = htons(DEST_PORT); servaddr.sin_addr = *((struct in_addr *) h_server->h_addr); /* * Open a TCP socket (an Internet stream socket). */ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { cerr << "client: can't open stream socket"; exit(1); } if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr)) < 0) { cerr << "client: can't connect to server"; exit(1); } int datalen; char sendline[BUF_SIZE], recvline[BUF_SIZE + 1]; while(cin.getline(sendline, BUF_SIZE)) { send(sockfd, sendline, strlen(sendline), 0); datalen = recv(sockfd, recvline, BUF_SIZE, 0); recvline[datalen] = '\0'; /* null terminate */ cout << recvline << endl; } close(sockfd); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <iostream> #define MY_PORT 12346 /* arbitrary, but client and server must agree */ #define BUF_SIZE 4096 #define MAX_PENDING 5 using namespace std; int main(int argc, char **argv) { int sockfd; struct sockaddr_in servaddr, cliaddr; socklen_t addrlen; /* * Open a UDP socket (an Internet datagram socket). */ if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { cerr << "server: can't open stream socket"; exit(1); } /* * Fill in the structure "servaddr" with the local address and port. * INADDR_ANY automatically fills in the local host's IP address. */ servaddr.sin_family = AF_INET; servaddr.sin_port = htons(MY_PORT); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* * Bind our local address so that the client can send to us. */ if (bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) { cerr << "server: can't bind local address"; exit(1); } /* * Read the next datagram arriving at the server's port and send * it back using sendto. The recvfrom function fills in cliaddr with * the IP address and port of the client that sent the data so that we * know where to send back the response. */ int datalen; char mesg[BUF_SIZE]; addrlen = sizeof (struct sockaddr_in); for( ; ; ) { datalen = recvfrom(sockfd, mesg, BUF_SIZE, 0, (struct sockaddr *)&cliaddr, &addrlen); mesg[datalen] = '\0'; cout << mesg << endl; sendto(sockfd, mesg, datalen, 0, (struct sockaddr *)&cliaddr, addrlen); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <iostream> #define DEST_PORT 12346 /* arbitrary, but client and server must agree */ #define BUF_SIZE 4096 using namespace std; int main(int argc, char **argv) { int sockfd; struct sockaddr_in servaddr; struct hostent *h_server; /* Read command line inputs. Get server host name and IP address. * The function gethostbyname() will return a structure containing * the IP address for the given host name. */ if (argc !=2) { cout << "Usage: client <server-name>" << endl; exit(1); } if ((h_server = gethostbyname(argv[1])) == NULL) { cerr << "client: can't get server address" << endl; exit(1); } /* * Fill in the structure "serv_addr" with the address and the * port of the server to which we are sending data. */ servaddr.sin_family = AF_INET; servaddr.sin_port = htons(DEST_PORT); servaddr.sin_addr = *((struct in_addr *) h_server->h_addr); /* * Open a UDP socket (an Internet datagram socket). */ if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { cerr << "client: can't open datagram socket"; exit(1); } int datalen; char sendline[BUF_SIZE], recvline[BUF_SIZE + 1]; while(cin.getline(sendline,BUF_SIZE) != NULL) { sendto(sockfd, sendline, strlen(sendline), 0, (struct sockaddr *)&servaddr, sizeof(servaddr)); datalen = recvfrom(sockfd, recvline, BUF_SIZE, 0, NULL, NULL); recvline[datalen] = '\0'; /* null terminate */ cout << recvline << endl; } close(sockfd); } |
C and C++ Resources
The following are helpful tutorials, tools, code and miscellaneous Java resources:
10 Major Differences Between C and C++
As always, please contact us with comments, concerns, questions, etc. about C/C++!