Socket programming in C++ is the way of combining or connecting two nodes with each other over a network so that they can communicate easily without losing any data. One socket (node) listens on a particular port at an IP, while the other socket reaches out to the other to form a connection. The server forms the listener socket while the client reaches out to the server.
If we take a real-life example then the socket we see in reality is a medium to connect two devices or systems. It can be either a phone charger plugging into the socket or a USB cable into our laptop. In the same way, Sockets let applications attach to the local network at different ports. Every time a socket is created, the program has to specify the socket type as well as the domain address.
Sockets are a mechanism for exchanging data between processes. These processes can either be on the same machine, or on different machines connected via a network. Once a socket connection is established, data can be sent in both directions until one of the endpoints closes the connection.
I needed to use sockets for a project I was working on, so I developed and refined a few C++ classes to encapsulate the raw socket API calls. Generally, the application requesting the data is called the client and the application servicing the request is called the server. I created two primary classes, ClientSocket and ServerSocket, that the client and server could use to exchange data.
The goal of this article is to teach you how to use the ClientSocket and ServerSocket classes in your own applications.
Procedure in Client-Server Communication:
- Socket: Create a new communication
- Bind: Attach a local address to a socket
- Listen: Announce willingness to accept connections
- Accept: Block caller until a connection request arrives
- Connect: Actively attempt to establish a connection
- Send: Send some data over a connection
- Receive: Receive some data over a connection
- Close: Release the connection
State diagram for server and client model:
Stages for Server: Socket Creation
Int socketcr = socket( domain , type, protocol )
Socketcr = It is like a descriptor ,an integer (file handle)
Domain = integer type, communication domain, example = AF_INET6 (IPv6 protocol)
Type = communication type
SOCK_DGRAM: UDP(unreliable, connectionless)
Protocol = Protocol value for Internet Protocol(IP), which is 0. This is the same number which appears on the protocol field in the IP header of a packet. (man protocols for more details)
What’s a connection?
A relationship between two machines, where two pieces of software know about each other. Those two pieces of software know how to communicate with each other. In other words, they know how to send bits to each other. A socket connection means the two machines have information about each other, including network location (IP address) and TCP port. (If we can use an analogy, IP address is the phone number and the TCP port is the extension).
A socket is an object similar to a file that allows a program to accept incoming connections, make outgoing connections, and send and receive data. Before two machines can communicate, both must create a socket object. A socket is a resource assigned to the server process. The server creates it using the system call socket(), and it can’t be shared with other processes.
Setsockopt: This helps in manipulating options for the socket referred by the file descriptor socket. This is completely optional, but it helps in the reuse of address and port. Prevents error such as: “address already in use”.
Blind: After the creation of the socket, bind function binds the socket to the address and port number specified in addr(custom data structure). In the example code, we bind the server to the localhost, hence we use INADDR_ANY to specify the IP address.
Listen: The listen() function marks a connection-mode socket (for example, those of type SOCK_STREAM), specified by the socket argument s, as accepting connections, and limits the number of outstanding connections in the socket listen to queue to the value specified by the backlog argument. The socket s is put into ‘passive’ mode where incoming connection requests are acknowledged and queued pending acceptance by the process.
The backlog parameter of this function is typically used by servers that could have more than one connection request at a time: if a connection request arrives with the queue full, the client receives an error with an indication of ECONNREFUSED.
listen() attempts to continue to function rationally when there are no available descriptors. It accepts connections until the queue is emptied. If descriptors become available, a later call to listen() or accept() re-fills the queue to the current or most recent backlog’, if possible, and resume listening for incoming connections.
Accept: The accept() system call is used with connection-based socket types(SOCK_STREAM, SOCK_SEQPACKET). It extracts the first connection request on the queue of pending connections for the listening socke sockfd, creates a new connected socket, and returns a new file descriptor referring to that socket. The newly created socket is not in the listening state. The original socket sockfd is unaffected by this call. The argument sockfd is a socket that has been created with socket(2), bound to a local address with bind(2), and is listening for connections after a listen(2).
Stages For Client:
Socket connection: Exactly same as that of server’s socket creation
Connect: The connect() system call initiates a connection on a socket. If the parameter s (a socket) is of type SOCK_DGRAM, then connect() permanently specifies the peer to which datagrams are to be sent. If s is of type SOCK_STREAM, then connect() attempts to make a connection to another socket. The name parameter specifies the other socket. The connect() function is used to create a connection to the specified foreign association. The parameter s specifies an unconnected datagram or stream socket. If the socket is unbound, the system assigns unique values to the local association, and the socket is marked as bound. For stream sockets (type SOCK_STREAM), an active connection is initiated to the foreign host using the name (an address in the namespace of the socket). When the socket call completes successfully, the socket is ready to send/receive data.
Send/Receive :- The send() and recv() calls specify:
- The sockets on which to communicate
- The address in the storage of the buffer that contains, or will contain, the data (addr_of_data, addr_of_buffer)
- The size of this buffer (len_of_data, len_of_buffer)
- A flag that tells how the data is to be sent
Steps to establish connection in socket:
The system calls for establishing a connection are somewhat different for the client and the server, but both involve the basic construct of a socket. A socket is one end of an interprocess communication channel. The two processes each establish their own socket.
The steps involved in establishing a socket on the client side are as follows:
- Create a socket with the socket() system call
- Connect the socket to the address of the server using the connect() system call
- Send and receive data. There are a number of ways to do this, but the simplest is to use the read() and write() system calls
The steps involved in establishing a socket on the server side are as follows:
- Create a socket with the socket() system call
- Bind the socket to an address using the bind() system call. For a server socket on the Internet, an address consists of a port number on the host machine
- Listen for connections with the listen() system call
- Accept a connection with the accept() system call. This call typically blocks until a client connects with the server
- Send and receive data
Use of socket programming:
Socket programs are used to communicate between various processes usually running on different systems. It is mostly used to create a client-server environment. This post provides the various functions used to create the server and client program and an example program. In the example, the client program sends a file name to the server and the server sends the contents of the file back to the client. Socket programming usually pertains to the basic communication protocols like TCP/UDP and raw sockets like ICMP. These protocols have a small communication overhead when compared to underlying protocols such as HTTP/DHCP/SMTP etc.
Some of the basic data communications between client and server are:
- File Transfer: Sends name and gets a file.
- Web Page: Sends URL and gets a page.
- Echo: Sends a message and gets it back.
- The C++ can establish communication only with the machine requested and not with any other machine on the network.
- Sockets allow only raw data to be sent. This means that both client and server need to have mechanisms to interpret the data.
Frequently Asked Questions
Socket Programming is used to establish communication between two network nodes.
Yes, socket programming is still widely used.
Java and C#/C++ are the best languages for socket Programming.
Socket programming is used to create endpoints to establish communication between network nodes.
Yes, socket programming can be done in Windows using Winsock.
To read more about C++, click here.
By Akhil Sharma