I was trying to get into the very deep understanding of socket programming in C++ not for the first time and finally I got it. That is why I am really eager to share the main things to know. Also wanna show that I was actually doing something these days:)
Below I listed The Elephants of socket programming (abstractly
). And all of them are very logical.
- socket(family, socktype, protocol)
- Necessary to create a socket descriptor that later will be fed to other system calls.
- Creation: Feed the information about the protocol version (4, 6, any), socket type (Stream, Datagram), protocol (0 or any)
- Returns: Socket Descriptor
- bind(sock_descriptor, addr, addrlen)
- Necessary to prepare to listen mode and binds to a random/free port
- Creation: Feed the socket descriptor, address information, address length
- Returns: -1 if error occurs
- listen(sock_descriptor, backlog)
- After binding to the port, listen mode can be turned on.
- Creation: Feed the socket descriptor from socket() and the number of connection in a queue(backlog)
- Returns: -1 if error occurs
- accept(sock_descriptor, addr, addrlen)
- After setting the listen mode, on incoming connection accept might be called.
- Creation: Feed the socket descriptor, address information where the information about the incoming connection will be stores, address length.
- Returns: -1 if error occurs
- connect(sock_descriptor, addr, addrlen)
- Necessary to connect to the remote host.
- Creation: Feed the socket descriptor, address information of remote host, address length.
- Returns: -1 if error occurs
- sockaddr_in/sockaddr addr: Contains of fields that are required to be filled:s_family, s_port , s_addr, s_zero.
- S_family: protocol version (4, 6, any)
- S_port: in network byte order: htons(atoi(port))
- S_addr: in binary format: inet_aton(“awesome_ip”, &addr.s_addr)
Note: All above is written in a kind of abstract way for better understanding the concept. More details can be found here.
Another cool thing to know:
- getsockname (sock_descriptor, addr, addrlen)
- Retrieves the locally-bounded neme of a specific socket and stores it to addr.
- getpeername (sock_descriptor, addr, addrlen)
- Retrieves the name of connected peer socket and stores it to addr.
Using these elephants will allow you to establish a connections between hosts, make them a server or client and do whatever. However some issues could appear, when you are sending an information through the network: How to ensure that on the other end of the wire a host will get exactly sent data when you want to send a binary, not text? For this serialization was created.
Serialization
There are three options to do it:
- sprintf() to make text. Sent. strtol() to get data from text. SLOW!
- Rend Raw data. Pass a pointer to the data to send(). DANGEROUS! NON_PORTABLE!
- Encode into a portable binary form. Decode it on the other end. RULES! More here on Chapter 7.4.
Casting in C++
A very cool thing exists in C++ for type conversion between classes and controlling inappropriate conversion.
- dynamic_cast <new_type> (expression)
- is used only to convert from pointers and ref to objects (from derived to parent classes).
- Purpose: Ensure conversion to valid complete object
- Success: Conversion from child to parent class OR Conversion from parent that point to child to child.
- static_cast <new_type> (expression)
- is used only to convert from pointers to related classes (also from parent classes to derived ones), used for any non-pointer converter like it is implicit cast, used for conversions between classes with explicit constructor.
- Purpose: Makes classes compatible, however no safety check is made.
- reinterpret_cast <new_type> (expression)
- is used only to convert from any pointer type to any other pointer type. It is actually just a binary copy of the value from one pointer to another.
- Purpose: Makes classes compatible, however no safety check is made.
- const_cast <new_type> (expression)
- Purpose: manipulates with const objects, either mark or not as const. Example: ass a const argument to the function as non const parameter.
- typeid
- Purpose: get an info about the type. Return: reference to the constant object of type type_info.
