The accept() function in the Socket API is used on the server side. It accepts a new connection request from the listening queue and creates a new socket for it.
When the server is listening on a port for client connection requests, the client initiates a connection request by calling the connect() function. At this point, the server's accept() function retrieves the connection request from the listening queue to process it.
The workflow of the accept() function is as follows:
- Waiting for Connection Requests: The
accept()function blocks until a connection request is received. - Extracting Connection Requests: Once a client connection request arrives, the
accept()function extracts the request from the listening queue and creates a new socket for the connection. This new socket is used for communication between the server and client, while the original socket continues to listen for other connection requests. - Returning the New Socket: The
accept()function returns the descriptor of the newly created socket. The server uses this new socket to exchange data with the client.
Example
Suppose you are implementing a simple server to receive client information. The server-side code may include the following part:
c#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> int main() { int sockfd, new_sockfd; // sockfd for listening, new_sockfd for new connection struct sockaddr_in host_addr, client_addr; // server and client address information socklen_t sin_size; int yes = 1; // Create socket if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) perror("socket"); // Set socket options if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) perror("setsockopt"); // Bind address to socket host_addr.sin_family = AF_INET; host_addr.sin_port = htons(4000); host_addr.sin_addr.s_addr = INADDR_ANY; memset(&(host_addr.sin_zero), 0, 8); if (bind(sockfd, (struct sockaddr *)&host_addr, sizeof(struct sockaddr)) == -1) perror("bind"); // Listen on port if (listen(sockfd, 5) == -1) perror("listen"); // Loop to accept connections while(1) { sin_size = sizeof(struct sockaddr_in); new_sockfd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size); if (new_sockfd == -1) perror("accept"); else { // Process new connection, e.g., send and receive data send(new_sockfd, "Hello, world!\n", 14, 0); // Close the new socket close(new_sockfd); } } return 0; }
In this example, the server uses socket() to create a listening socket, then uses bind() to bind the address, and listen() to start listening. When a client connects, accept() is called to accept the connection and generate a new socket new_sockfd for communication with the client. Afterward, data can be sent to the client or received from the client using this new socket.