Using the Accept() Function to Listen for Connections on a Socket
The function which is known as “accept()” function is used to listen for connection on a socket. This function mainly blocks the program execution until and unless a client connection is created. As soon as a connection is made, this function returns a new socket descriptor that is used for client communication. Let us see the programming example which uses the “accept()” function for connection on a socket.
Programming Example 1:
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main ()
{
int server_soc, client_soc;
struct sockaddr_in server_address, client_address;
socklen_t client_length;
// Create the server socket
server_soc = socket (AF_INET, SOCK_STREAM, 0);
// Bind the socket to a specific address and port
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_port = htons (7070);
bind (server_soc, (struct sockaddr*)&server_address, sizeof(server_address));
// Start listening for connections
listen (server_soc, 5);
printf ("Server is waiting for client connections \n");
// Accept incoming connections
client_length = sizeof (client_address);
client_soc = accept (server_soc, (struct sockaddr*)&client_address, &client_length);
printf ("Client has been connected! \n");
// close the client socket
close (client_soc);
// Continue listening for more connections
while (1) {
client_soc = accept (server_soc, (struct sockaddr*)&client_address, &client_length);
printf("Client has been connected! \n");
close (client_soc);
}
// Close the server socket
close (server_soc);
return 0;
}
Output:
$ ./soc
Server is waiting for client connections
The programming example creates a server socket and binds it to a certain address and port. It then watches for new connections. When a client connects, a message which indicates the connection is shown. After that, this code continues to listen for new connections and prints the connection each time.
Using the Epoll() Function to Listen for Connections on a Socket
This function can also be used to listen for connections on a socket in the C programming language. Let us see the use of the “epoll()” function in our programming example.
Programming Example 2:
#include <stdlib.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define MAX_EVENTS 10
int main () {
int serverSocket, clientSocket;
struct sockaddr_in serverAddress, clientAddress;
socklen_t clientLength;
// Create the server socket
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
// Bind the socket to a specific address and port
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = INADDR_ANY;
serverAddress.sin_port = htons(8080);
bind (serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
// Start listening for connections
listen (serverSocket, 5);
printf ("Server is waiting for client connections!!!\n");
// Create epoll instance
int epollfd = epoll_create1 (0);
if (epollfd == -1) {
perror ("epoll_create1");
exit (EXIT_FAILURE);
}
// we have to register the server socket for “epoll” events
struct epoll_event event;
event.events = EPOLLIN;
event.data.fd = serverSocket;
if (epoll_ctl (epollfd, EPOLL_CTL_ADD, serverSocket, &event) == -1) {
perror ("epoll_ctl");
exit (EXIT_FAILURE);
}
// Buffer to hold events
struct epoll_event events[MAX_EVENTS];
while (1) {
int numEvents = epoll_wait (epollfd, events, MAX_EVENTS, -1);
if (numEvents == -1) {
perror ("epoll_wait");
exit (EXIT_FAILURE);
}
// Process events
for (int i = 0; i < numEvents; i++) {
// Check if the event is for the server socket
if (events[i].data.fd == serverSocket) {
// Accept incoming connection
clientLength = sizeof (clientAddress);
clientSocket = accept (serverSocket, (struct sockaddr*)&clientAddress, &clientLength);
printf ("Client connected!\n");
// Further handling of the client connection will be done here
// now we Close the client socket
close (clientSocket);
}
}
}
// now we Close the server socket
close (serverSocket);
return 0;
}
Output:
$ ./soc
Server is waiting for client connections!!!
Here, we use the “epoll()” function to create a server. This server is listening for incoming connections. We can use the “epoll()” function when there are many clients connection. The server socket has “epoll()” and reads the registered events. A new connection is identified when it is discovered. In this program, we also use the “epoll_wait()” loop which waits for events and handles them in this program. Until and unless the program is expressly cancelled, the server continues to wait for connections from the client server.
Conclusion
Listening for connections on a socket in C is a fundamental aspect of server applications. We discussed about two approaches which are the traditional “accept()” method and the “epoll()”
method mechanism in the article. The “accept()” approach involves blocking and waiting for connections, while “epoll()” uses the event-driven programming to listen to multiple connections. Both methods have their strengths and we can use as per our programming requirements.