C
listen and accept
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.
Exercise 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.
Show example 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;
}
Test yourself
-
listen call
listen(fd, ____);
Show answer
listen(fd, 5);
-
Match listening steps
- listen
- Starts listening
- accept
- Accepts connection
- backlog
- Queue length
- fork
- Creates process
-
What does accept return?
- The old descriptor
- A byte count
- A new descriptor
- An address struct
Show answer
A new descriptor — accept returns a new descriptor for the client.
Next lesson: connect