I am learning socket programming in c and trying to understand what exactly is listen()
doing in the code. I understand it defines the maximum number of connection that can be queued for accept()
but other than that I can't seem to understand what else is it doing.
According to the text I'm learning from,
listen() waits for incoming connections. Accept() gets the pending connection on the port you are listen()ing.
Looking at the flow of execution, I see that listen()
is, in fact, called only once and after that only accept() is handling whatever new connection that comes in. Then, how does the server listen the future requests if listen() is never called once we get inside the accept loop.?
+----------+
|socket() |
+----------+
+----------+
|bind() |
+----------+
+----------+
|listen() |
+----------+
+----------+
|while(1) |
|----------|
|accept() |
| |
| |
+----------+
Here's the code I am working on:
/*Server*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
int main()
{
int sockfd, newsock;
char buffer[200];
memset(buffer, 0, sizeof(buffer));
/*Creating a new socket*/
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("Socket error");
exit(1);
}
/*Creating socket address structure*/
struct sockaddr_in server_addr, client_address;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(7200);
server_addr.sin_addr.s_addr = inet_addr("192.168.1.2");
bzero(&(server_addr.sin_zero),8);
/*Binding*/
if(bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
perror("Bind error");
exit(1);
}
/*Listening for new connection; maximum 5*/
if(listen(sockfd, 5) < 0)
{
perror("Listen error");
}
while(1)
{
socklen_t len = sizeof(client_address);
if((newsock = accept(sockfd, (struct sockaddr *)&client_address, &len)) < 0)
{
perror("Accept error");
exit(1);
}
int i;
if((i = read(newsock, buffer, sizeof(buffer))) < 0)
{
perror("Receive error");
exit(1);
}
if(i == 0)
{
printf("Socket closed remotely\n");
}
if(i > 0)
{
printf("received %d bytes\n",i);
printf("data: %s",buffer);
}
close(newsock);
}
close(sockfd);
return 0;
}