C++ Socket Programming
In this world, computer networking has become very important for sharing of data. Every good programmer has some knowledge about computer networking. Socket programming is one of the critical topics in computer networking. In this article, we will learn the topic of socket programming.
In C++, socket programming is the way of connecting two nodes over a network. With the help of socket programming, sharing of data between two nodes is possible without losing any data. One socket is connected to a particular port at an IP address, and the other socket is associated with the server.
What is a Socket?
In real life, the socket is used as a medium that is used to connect the two devices. It can be either a phone charger plugged into the socket or a USB cable into our laptop. In the same manner, the socket is used in the local network for communication purpose. When a socket is created simultaneously, its domain address has been created by the programs. The socket is used the exchanging the data between processes. These processes may be available on the same or different devices. With the help of a socket, the transfer of data is possible in both directions. There are two classes that are used in socket programming. These two classes are ClientSocket and ServerSocket.
Procedure in Client-Server Communication
- Socket- It is used to create a new communication.
- Bind- It is used to attach the local address to a socket.
- Listen- It is used to accept the connection.
- Accept- It is used to block the caller.
- Connect- It is used to establish the connection.
- Send- It is used to send the data over a connection.
- Received- It is used to receive the data over a connection.
- Close- It is used to release the connection.
What is a connection?
Connection is a type of relationship between two machines where two machines know about each other. They also know how to communicate with each other. A socket connection means two machines have information about each other, and the information is like network location (IP address) and TCP port. A socket is also similar to a program that is used for sending and receiving data, accepting the incoming connection and making outgoing connections. The server assigns the sockets. With the help of socket(), the server creates the socket. These sockets cannot be shared with another process.
Setsockopt: With the help of this server call, the file referred to the socket. It also helps us to reuse the address and port. It also prevents errors such as “address already in use”.
Bind: After the socket is created, then the bind call is used to connect the address and port number.
Listen: We used to listen to calls to make a program that allows the incoming connection. It is specified by socket arguments. It accepts the connection until the queue becomes completely empty. The backlog parameter is used to accept more than one connection at a time.
Accept: There are two types of connection-based sockets. These two sockets are SOCK_STREAM and SOCK_SEQPACKET. The accept() system call is worked with the combination of these two sockets. It is used to extract the connection which comes first from the queue. Then it creates a new connection for the socket. Then it returns a new file descriptor that refers to the socket. But the new socket is not in the listenable connection because The accept() affects the new socket. Then a new socket, i.e. argument sockfd, has been created with that second socket. After that, the dual-socket binds a connection and listen to all the socket.
Stages for Client
Socket connection: The socket connection for the client is the same as the socket connection for the server.
Connect: With the help of connecting (), we can initiate the connection for the socket. If the socket parameter “s” is a SOCK_DGRAM, then the data are sent permanently over the connection. If the socket parameter “s” is a SOCK_STREAM, then we can attempt the connection with another socket. So the name parameter decides the type of connection for the socket. The primary function of connect() call is to establish a connection with a foreign association. Here the parameter “s” is used for the unconnected datagram. For the socket type SOCK_STREAM, an active connection is initiated with the host. When the socket function calls successfully, the data are ready for sending over the connection.
Send/Receive: With the help of sending or receiving the call, we can able to communicate between two sockets. The address of stored data can be obtained by the addr_of_data, addr_of_buffer call. We can also calculate the buffer size by the len_of_data and len_of_buffer calls.
Steps to establish the connection in the socket:
The system call can establish a connection between a different client and server, but both are involved in the process of construction of the socket. A socket is used as the end of the interprocess communication between client and server. Both client and server have their own socket to establish the connection.
The steps involved in connecting a socket on the client side-
- We can create a socket with the help of a socket call.
- Then connect the socket to the server’s address with the help of a system call.
- Then use the read() and write() system call for sending and receiving the data over the connection.
The steps involved in connecting a socket on the server side-
- Create a socket with the help of a socket call.
- With the help of bind(), we attach the socket with an address. There is a port number for every server socket address.
- With the help of the listening () system call, we can listen for the connection.
- With the help of accept() system call, we can accept the connection. When the client connects with the server, then acceptance of the relationship starts.
- After that, sending and receiving data is possible over the connection.
Connecting Multiple Clients Without Multithreading
It is possible that multiple clients are also connected to a single server. This is possible by many methods. One of the methods among them is Multithreading. But the Multithreading process is complicated to code and debug, and also, the result is unpredictable. There is a chance of occurring of deadlock during the process. So we do not have to use the Multithreading process. Instead of Multithreading, we should use a select() system call.
What is the select() function?
The select () system call is a Linux command. It allows the server to monitor multiple file descriptors. After the data are sent by a file descriptor, it is activated. So we also called it an interrupt handler. Select() system call also provides the information of data that is read by the socket. It also gives information on the total number of sockets that are ready for connection.
There are four types of macros that are associated with the select() system call.
- *FD_ZERO(set): It shows the total number of empty sets. All the sets should be clear before the connection.
- *FD_CLR(s, set): It removes all the sockets from an empty set.
- *FD_ISSET(s, set): it checks if the member returns back the actual value or not.
- *FD_SET(s, set): With the help of this call, we can add a socket in the sets,
With the help of these four macros and one select system call, we can handle multiple connections in a single server.