listen and accept
- C course
- Advanced
- Lesson 27/83
- 5 min
Learn to accept connections with listen and accept.
listen and accept
listen(fd, backlog) puts the socket into passive listening mode. backlog is the length of the pending connection queue; usually 5. After this the socket is ready to accept connections.
accept(fd, NULL, NULL) accepts an incoming connection and returns a new descriptor. The original socket keeps listening; the new descriptor is for communicating with the client. accept blocks until a connection arrives. The client connects with connect; details in the next lesson.
Accepting connections
When the server calls accept, it waits until a client connects with connect. When a connection arrives, accept returns a new descriptor.
You exchange data over this descriptor with send and recv. For testing, you can run server and client in the same program with fork: the parent listens, the child connects. This guarantees ordering and makes the output deterministic.
Practice Accept a connection
Create a socket, call bind and listen(listen_fd, 1). Fork a child; in the child call connect(cfd, (struct sockaddr *)&addr, sizeof(addr)). In the parent call int client_fd = accept(listen_fd, NULL, NULL); and printf("accepted\n");. Use path /tmp/cb_l.sock.
Starter code
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <string.h>
// Create socket, bind and listen
// Fork a child, child does connect
// Parent accept and print
int main(void) {
return 0;
}Sample solution
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <string.h>
int main(void) {
int listen_fd = socket(AF_UNIX, SOCK_STREAM, 0);
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, "/tmp/cb_l.sock", sizeof(addr.sun_path) - 1);
unlink("/tmp/cb_l.sock");
bind(listen_fd, (struct sockaddr *)&addr, sizeof(addr));
listen(listen_fd, 1);
pid_t pid = fork();
if (pid == 0) {
int cfd = socket(AF_UNIX, SOCK_STREAM, 0);
connect(cfd, (struct sockaddr *)&addr, sizeof(addr));
close(cfd);
_exit(0);
}
int client_fd = accept(listen_fd, NULL, NULL);
printf("accepted\n");
close(client_fd);
close(listen_fd);
unlink("/tmp/cb_l.sock");
return 0;
}Expected output
accepted
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 listen call
listen(fd, ____);
listen(fd, 5);
Explanation: A backlog of 5 is the pending queue length.
2 Match listening steps
| Term | Meaning |
|---|---|
listen |
Starts listening |
accept |
Accepts connection |
backlog |
Queue length |
fork |
Creates process |
3 What does accept return?
- The old descriptor
- A byte count
- A new descriptor Correct answer
- An address struct
Explanation: accept returns a new descriptor for the client.