Devember: I/O Multiplexing using select

This post is part of the Devember collection, useful for the study of the Socket API.

Devember: I/O Multiplexing using select

A few days ago, I wrote a simple echo Client that however has some robustness problems. For example, while the client is blocked in a request for user input and the server closes the connection, the client will not aware of that until it try to send data. The I/O Multiplexing solves that problem.

Using the select function we can operate on more than one descriptor:

FILE *fp;
int sockfd;
// ...
fd_set readset;
FD_ZERO(&readset);
FD_SET(fileno(fp), &readset);
FD_SET(sockfd, &readset);
int maxfd = MAX(fileno(fp), sockfd) + 1;
if (select(maxfd, &readset, NULL, NULL, NULL) < 0) {
	perror("select");
	return -1;
}

Then, when the select returns, we checks whether the descriptors are ready to operate:

if (FD_ISSET(sockfd, &readset)) {
	if ((n = exso_readln(sockfd, recvline, MAXLINE)) < 0) {
		perror("exso_readln");
		return -1;
	}
	if (n == 0) {
		printf("Server terminated prematurely\n");
		return -1;
	}
	fputs(recvline, stdout);
}

if (FD_ISSET(fileno(fp), &readset)) {
	if (fgets(sendline, MAXLINE, fp) == NULL) {
		return 0;
	}
	if (exso_writen(sockfd, sendline, strlen(sendline)) < 0) {
		perror("exso_writen");
		return -1;
	}
}

The complete code can be found on this repository.

9 December 2015