Reputation: 294
This is a figure to demonstrate a typical client-server model from The Linux Programming Interface
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
sockfd
, output of socket()
connfd
, output of accept()
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
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
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