dustin2022
dustin2022

Reputation: 294

Why does accept() create a new socket?

This is a figure to demonstrate a typical client-server model from The Linux Programming Interface

enter image description here

This is a sample source code for server-side from geeksforgeeks

#include <stdio.h> 
#include <netdb.h> 
#include <netinet/in.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <sys/types.h> 
#define MAX 80 
#define PORT 8080 
#define SA struct sockaddr 
  
// Function designed for a chat between client and server. 
void func(int sockfd) 
{ 
    // server's job
} 
  
// Driver function 
int main() 
{ 
    int sockfd, connfd, len; 
    struct sockaddr_in servaddr, cli; 
  
    // socket create and verification 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    if (sockfd == -1) { 
        printf("socket creation failed...\n"); 
        exit(0); 
    } 
    else
        printf("Socket successfully created..\n"); 
    bzero(&servaddr, sizeof(servaddr)); 
  
    // assign IP, PORT 
    servaddr.sin_family = AF_INET; 
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    servaddr.sin_port = htons(PORT); 
  
    // Binding newly created socket to given IP and verification 
    if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) { 
        printf("socket bind failed...\n"); 
        exit(0); 
    } 
    else
        printf("Socket successfully binded..\n"); 
  
    // Now server is ready to listen and verification 
    if ((listen(sockfd, 5)) != 0) { 
        printf("Listen failed...\n"); 
        exit(0); 
    } 
    else
        printf("Server listening..\n"); 
    len = sizeof(cli); 
  
    // Accept the data packet from client and verification 
    connfd = accept(sockfd, (SA*)&cli, &len); 
    if (connfd < 0) { 
        printf("server acccept failed...\n"); 
        exit(0); 
    } 
    else
        printf("server acccept the client...\n"); 
  
    // Function for chatting between client and server 
    func(connfd); 
  
    // After chatting close the socket 
    close(sockfd); 
} 

In the book I mentioned above, the author said

The key point to understand about accept() is that it creates a new socket, and it is this new socket that is connected to the peer socket that performed the connect().

In server's source code, there are 2 sockets

Why doesn't server-side use sockfd to "talk" to the client, but create a new socket - connfd then "talks" to the client while there's a socket already existed?

Upvotes: 3

Views: 2769

Answers (2)

dbush
dbush

Reputation: 223719

A listening socket can be used to accept multiple connections, each with a different remote IP/port pair.

A TCP connection is defined by 4 values: source IP, source port, destination IP, destination port. A socket descriptor returned by accept is associated with such a connection. In contrast, the listening socket is only associated with a local IP and port.

In this particular code example it only calls accept once. But it could do so in a loop to handle connections from multiple endpoints. Typically, such a process would have one thread calling accept in a loop. Then when a new socket is returned from accept, a new thread is started to handle that connection while the main thread calls accept again.

Upvotes: 5

Remy Lebeau
Remy Lebeau

Reputation: 595792

A server can have multiple clients connected to it at a time. A single socket descriptor can't represent multiple connections. Each connection consists of a unique combination of local + peer address/port pairs, so the server needs a separate socket descriptor to represent each one.

Upvotes: 1

Related Questions